Problem bei Consolenausgabe



  • Hallo, ich habe mir ein Konsolengrundgerüst geschrieben indem die Tasten-Operationen wie ENTER, BACKSPACE, usw. selbst definiert sind und der string ohne getline() eingelesen wird. Die Tasten werden jeweils mit getch() abgefragt und in einer Switch-Anweisung werden die jeweiligen Tastencodes bearbeitet.

    ConsoleKeyInput.cpp

    #include <windows.h>
    #include <string>
    #include <iostream>
    #include <conio.h>
    #include "ic.hpp" //Improved Console
    
    #define ENTER            13
    #define BACKSPACE        8
    #define TAB				 9
    #define LEERTASTE        32
    #define ESCAPE            27
    #define STEUERZEICHEN    224
    #define PFEIL_LINKS        75
    #define PFEIL_RECHTS    77
    #define PFEIL_OBEN		72
    #define PFEIL_UNTEN		80
    #define DELETE            83
    
    #pragma comment(lib, "User32.lib")
    
    using namespace std;
    using namespace ic; // Auflösen des Improved Console-Namespace
    
    void gotoxy(short x, short y)
    {
    	HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    	COORD pos;
    	pos.X = x;
    	pos.Y = y;
    	SetConsoleCursorPosition(hCon, pos);
    }
    
    void clearLineAt(string prompt)
    {
    	cout.put( '\r' );
    
    	//Lösche alles ab der Prompt bis zum Ende der Konsole (Improved Console)
    	for( string::size_type i = prompt.length(); i < con.getWndSizeX() ; ++i )
    	{
    		cout.put( ' ' );
    	}
    	//cout << prompt << flush;
    	cout << '\r' << prompt << flush;   
    }
    
    int main()
    {
    	bool do_exit = false;
    	int x, y, key, currentPosition, textpos = 0;
    	string prompt = ":\\>";
    	string input;
    
    	//Handle für x,y Koordinaten
    	HANDLE std_output = GetStdHandle( STD_OUTPUT_HANDLE );
    	CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info;  
    
    	do
    	{
    		cout << prompt;	
    
    		do
    		{
    			key = _getch( );
    			switch(key)
    			{			
    
    			case BACKSPACE:
    				if(textpos > 0)
    				{
    					input.erase(textpos-1, 1);
    
    					GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    					y = console_screen_buffer_info.dwCursorPosition.Y;
    
    					currentPosition = prompt.length() + textpos;
    					gotoxy(currentPosition-1, y); 
    					textpos--;
    
    				}break;
    
    			case ENTER:		
    
    				input.append("\0");
    				//textpos = 0;
    				break;
    
    			case LEERTASTE:
    
    				clearLineAt( prompt );
    				input.insert(textpos, " "); 
    				cout << input << flush;
    
    				GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    				y = console_screen_buffer_info.dwCursorPosition.Y;
    
    				currentPosition = prompt.length() + textpos;
    				gotoxy(currentPosition+1, y);  
    				textpos++;                           
    
    				break;
    
    			case ESCAPE:
    
    				textpos = 0;
    				clearLineAt( prompt );
    				input = "";
    				break;
    
    			case STEUERZEICHEN:
    
    				switch( _getch() )
    				{
    				case PFEIL_LINKS: // Pfeiltaste nach Links      
    					if(textpos > 0)
    					{	
    						GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    						y = console_screen_buffer_info.dwCursorPosition.Y;
    
    						currentPosition = prompt.length() + textpos;
    						gotoxy(currentPosition-1, y);  
    						textpos--;
    
    					}break;
    
    				case PFEIL_RECHTS: // Pfeiltaste nach Rechts: 
    					if(textpos < input.length() )
    					{
    						GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    						y = console_screen_buffer_info.dwCursorPosition.Y;
    
    						currentPosition = prompt.length() + textpos;
    						gotoxy(currentPosition+1, y);  
    						textpos++; 
    
    					}break;
    
    				case DELETE:
    					if(input.length() > 0)
    					{
    						//clearLineAt( prompt );
    						input.erase(textpos, 1 );
    						//cout << input << flush;  
    
    						GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    						y = console_screen_buffer_info.dwCursorPosition.Y;
    
    						currentPosition = prompt.length() + textpos;
    						gotoxy(currentPosition, y);
    
    					}break;
    
    				}break;
    
    			default:
    
    				string tmp;
    				GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    				y = console_screen_buffer_info.dwCursorPosition.Y;
    
    				//An bestimmter Stelle im String wird neues Zeichen eingefügt
    				if(textpos < input.length() )
    				{
    					clearLineAt( prompt );
    
    					tmp = key;
    					input.insert(textpos, tmp);
    					cout << input << flush;
    				}
    
    				else
    				{					
    					input += key;
    					cout.put( key );
    				}
    				currentPosition = prompt.length() + textpos;
    				gotoxy(currentPosition+1, y);  
    				textpos++;
    			}
    		}while( key != ENTER );
    
    		cout << endl;
    
    		if( input.length() )
    		{			
    			cout << "Input: [" << input << "] CursorPos: " << textpos << endl << endl; 
    			textpos = 0;
    			//input.clear();			
    		}
    
    		if( input == "exit" )
    		{           
    			do_exit = true;
    		}	
    
    		//Lösche input string
    		input.clear();
    
    	}while( !do_exit);
    
    	return 0;
    }
    

    Mein Problem sind die Tasten BACKSPACE und DELETE. Der string wird richtig gelöscht.
    Aber ich weiß nicht wie ich diesen ausgeben soll, denn wenn ich mit cout ausgebe wird der alte überschrieben, dann ist noch die Position wichtig also wie kann man das realisieren mit der Ausgabe????



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum DOS und Win32-Konsole verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ich habe versucht beim BACKSPACE wo das letzte Zeichen gelöscht wird ein cout.put(' ') einzusetzen aber dann wird der teilstring vom ende nicht neu geschrieben, d.h. der string müsste dann neu ausgegeben werden:

    case BACKSPACE:
    				if(textpos > 0)
    				{
    					input.erase(textpos-1, 1);			
    					cout.put(' '); //Hier liegt das Problem, wenn ich im String ein paar zeichen lösche muss der rest nach vorne gezogen werden
    
    					GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    					y = console_screen_buffer_info.dwCursorPosition.Y;
    
    					currentPosition = prompt.length() + textpos;
    					gotoxy(currentPosition-1, y); 
    					textpos--;
    
    				}break;
    

    Hoffentlich kann mir jemand weiterhelfen, weiß langsam nicht weiter 😞



  • Ich weiss nicht ob es dir helfen wird?

    Bei der Asgabe in die console sind die Spalten und Zeilen relewant.
    die x koordinate muss du auch irgendwie einbauen.

    y = console_screen_buffer_info.dwCursorPosition.Y;
    x = console_screen_buffer_info.dwCursorPosition.X;
    


  • @Ramsis: Das mit den x,y Koordinaten hab ich schon.

    Wie bekomme ich den String input so ausgegeben das ich nicht jedesmal die ganze Zeile löschen muss und dann den String mit cout ausgebe, hat jemand eine Idee????



  • Weiß niemand um Rat ???


Anmelden zum Antworten