Brauche Hilfe bei eigener getline() Funktion



  • Hallo, ich habe mir eine Funktion geschrieben die ein string einliest wie die getline() Funktion und diese dann zurückgibt. Alles wird manuell mit getch() eingelesen und zu einem string zusammengebaut. Hab es schon fast geschafft die strings werden richtig verarbeitet, aber ich habe Probleme bei:

    Wenn man im string mit den Cursor Tasten(rechts,links) navigiert und bestimmte teile löschen/entfernen möchte, dann wird der string schon richtig verarbeitet, aber nicht 1:1 auf der Konsole ausgegeben wie es sein soll.

    Könnt ihr mir bitte weiterhelfen:

    #include <windows.h>
    #include <string>
    #include <iostream>
    #include <conio.h>
    
    #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
    
    using namespace std;
    
    void clearLine(int LineSize)
    {
    	cout.put( '\r' );
    
    	for( string::size_type i = 0; i < LineSize; ++i )
    	{
    		cout.put( ' ' );
    	}
    }
    
    void gotoxy(short x, short y)
    {
    	HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    	COORD pos;
    	pos.X = x;
    	pos.Y = y;
    	SetConsoleCursorPosition(hCon, pos);
    }
    
    string GetKeyInputString(string Prompt)
    {
    	//Cursor Position
    	int textpos = 0;
    	int key, x, y, currentPosition;	
    	string input;
    	int LineSize;
    
    	//Handle für x,y Koordinaten
    	HANDLE std_output = GetStdHandle( STD_OUTPUT_HANDLE );
    	CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info;  
    
    	do
    	{
    		key = _getch( );
    		switch(key)
    		{			
    
    		case BACKSPACE:
    			if(textpos > 0)
    			{					
    				input.erase(textpos-1, 1);
    				cout.put(' ');
    
    				GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    				y = console_screen_buffer_info.dwCursorPosition.Y;
    
    				currentPosition = Prompt.length() + textpos;
    				gotoxy(currentPosition-1, y); 
    				textpos--;		
    				break;
    			}
    
    			if(textpos == 0)
    			{
    				cout.put(' ');
    				GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    				y = console_screen_buffer_info.dwCursorPosition.Y;
    
    				currentPosition = Prompt.length() + textpos;
    				gotoxy(currentPosition, y); 
    				break;
    			}			
    
    		case ENTER:		
    			break;
    
    		case LEERTASTE:
    
    			input.insert(textpos, " "); 
    
    			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:
    
    			LineSize = Prompt.length() + input.length();
    			clearLine(LineSize);
    			cout << '\r' << Prompt << flush;   
    			textpos = 0;
    			input.clear();
    			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)
    				{					
    					input.erase(textpos, 1 );
    
    					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() )
    			{		
    				tmp = key;
    				input.insert(textpos, tmp);				
    			}
    
    			else
    			{					
    				input += key;
    				cout.put( key );
    			}
    			currentPosition = Prompt.length() + textpos;
    			gotoxy(currentPosition+1, y);  
    			textpos++;
    		}
    
    	}while( key != ENTER );
    
    	cout << endl;
    
    	if( input.length() != 0)
    	{				
    		cout << "Input: [" << input << "] CursorPos: " << textpos << endl << endl; 
    		return input;		
    	}
    	return "";
    }
    
    int main()
    {	
    	bool do_exit = false;
    	string Prompt = ":\\>";
    	string GetInput;
    
    	do
    	{
    		cout << Prompt;
    		GetInput = GetKeyInputString(Prompt);
    
    		if(GetInput == "exit")
    			do_exit = true;		
    
    	}while( !do_exit );
    
    	return 0;
    }
    


  • //....
                //An bestimmter Stelle im String wird neues Zeichen eingefügt
                if(textpos < input.length() )
                {
                    tmp = key;
                    input.insert(textpos, tmp);
    
                }
    
                else
                {
                    input += key;
                    cout.put( key );
                }
    
                gotoxy(3,y);     // <<<<----
                cout << input;   // <<<<----
    //....
    


  • #include <windows.h>
    #include <string>
    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    /*
    void clearLine(int LineSize)
    {
        cout.put( '\r' );
    
        for( string::size_type i = 0; i < LineSize; ++i )
        {
            cout.put( ' ' );
        }
    }*/
    
    class Prompt
    {
    public:
    	Prompt( string p ) : prompt(p)
    	{
    		std_output = GetStdHandle( STD_OUTPUT_HANDLE );
    	}
    	~Prompt() {}
    
    	string input();
    
    private:
    
    	void getCurrentxy( short& x, short& y )
    	{
    	    GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info );
    	    x = console_screen_buffer_info.dwCursorPosition.X;
    	    y = console_screen_buffer_info.dwCursorPosition.Y;
    	}
    
    	void gotoxy(short x, short y)
    	{
                COORD pos;
                pos.X = x;
                pos.Y = y;
                SetConsoleCursorPosition(std_output, pos);
    	}
    
    	string prompt;
    	HANDLE std_output;
    	CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info;
    
    	static const int KEY_ENTER = 13;
    	static const int KEY_BACKSPACE = 8;
    	static const int KEY_TAB = 9;
    	static const int KEY_LEERTASTE = 32;
    	static const int KEY_ESCAPE = 27;
    	static const int KEY_STEUERZEICHEN = 224;
    	static const int KEY_PFEIL_LINKS = 75;
    	static const int KEY_PFEIL_RECHTS = 77;
    	static const int KEY_PFEIL_OBEN = 72;
    	static const int KEY_PFEIL_UNTEN = 80;
    	static const int KEY_DELETE = 83;
    
    };
    
    string Prompt::input()
    {
        //Cursor Position
        unsigned int textpos = 0;
        int key;
    	short x, y;
        string input;
    
    	cout << prompt;
    
        do
        {
            key = _getch( );
            switch(key)
            {           
    
            case KEY_BACKSPACE:
    		{
    			if( textpos == 0 ) break;
    
    			getCurrentxy(x, y);
    			int save_x = x;
    
    			if( textpos < input.length() )
                {
    
    				int len = input.length() - textpos;
    
    				for( int i = 0; i < len; ++i)
    				{
    					gotoxy(x+i-1, y);
    					cout.put( input[textpos] );
    				}
    
    				gotoxy(x+len-1,y);
    				cout.put(' ');
    
    				gotoxy(save_x, y);
    				input.erase(textpos-1, 1);
                }
    			else
    			{
    				gotoxy(x-1, y);
    				cout.put( ' ');
    			}
    
    			gotoxy(x-1, y);
    			textpos--;
    
    			break;
    		}
            case KEY_ENTER:       
                break;
    
            case KEY_LEERTASTE:
    
                input.insert(textpos, " ");
                getCurrentxy(x, y);
    
                if(textpos < input.length() )
    			{
    				for( unsigned int i = textpos; i < input.length(); ++i)
    				{
    					cout.put( input[i] );
    					gotoxy(x+(i-textpos)+1, y);
    				}
    			}
    			else
    			{
    				cout.put( ' ' );
    			}
    
    			gotoxy(x+1, y);  
    			textpos++;
    
                break;
    
            case KEY_ESCAPE:
    
    			cout.put( '\r' );
    
    			for( unsigned int i = 0; i < prompt.length() + input.length(); ++i )
    			{
    				cout.put( ' ' );
    			}
    
                cout << '\r' << prompt << flush;  
                textpos = 0;
                input.clear();
                break;
    
            case KEY_STEUERZEICHEN:
    
                switch( _getch() )
                {   
    
                case KEY_PFEIL_LINKS: // Pfeiltaste nach Links      
                    if(textpos > 0)
                    {   
                        getCurrentxy(x, y);
                        gotoxy(x-1, y);
    
                        textpos--;
                    }break;
    
                case KEY_PFEIL_RECHTS: // Pfeiltaste nach Rechts:
                    if(textpos < input.length() )
                    {
                        getCurrentxy(x, y);
                        gotoxy(x+1, y);
    
                        textpos++;
                    }break;
    
                case KEY_DELETE:
                    if(input.length() > 0)
                    {
                        input.erase(textpos, 1 );
    
    					int len = input.length() - textpos;
    					getCurrentxy(x, y);
    					int save_x = x;
    
    					for( int i = 0; i < len; ++i )
    					{
    						gotoxy(x+i, y);
    						cout.put( input[textpos+i] );
    					}
    
    					gotoxy(x+len,y);
    					cout.put(' ');
    
    					gotoxy(save_x, y);
    
                    }break;
    
                }break;
    
            default:
    
    			string tmp;
    			getCurrentxy(x, y);
    
                //An bestimmter Stelle im String wird neues Zeichen eingefügt
                if(textpos < input.length() )
                { 
                    tmp = key;
                    input.insert(textpos, tmp);
    
    				for( unsigned int i = textpos; i < input.length(); ++i)
    				{
    					cout.put( input[i] );
    					gotoxy(x+(i-textpos)+1, y);
    				}
                }
                else
                {                   
                    input += key;
                    cout.put( key );
    			}
    
    			gotoxy(x+1, y);
                textpos++;
    
            }
    
        }while( key != KEY_ENTER );
    
        cout << endl;
    
        if( input.length() != 0)
        {               
            cout << "Input: [" << input << "] CursorPos: " << textpos << endl << endl;
            return input;       
        }
        return input;
    }
    
    int main()
    {   
        Prompt in(":\\>");
    
        while(1)
        {
    		if(in.input() == "exit") 
    			break;      
        }
    
        return 0;
    }
    


  • @Ramsis: Danke für die Mühe 🙂

    Habe noch ein Schönheitsfehler gefunden, wenn man mit BACKSPACE ein string löscht wird das letzte zeichen jedesmal an der cursorposition ausgegeben. Und wenn man in der mitte des Strings ein bestimmten teil löschen will, wird hinter der cursorposition ein falscher inhalt ausgegeben.



  • Leute könnt ihr mir bitte weiterhelfen, es geht um den Code von Ramsis:

    Wenn man in der Zeile hinweg schreibt, also in die nächste Zeile springt und so weiter, dann kann man mit den Tastenoperationen nicht in der hervorige Zeile zurückspringen z.B. beim Backspace oder die Pfeiltasten(links) Wahrscheinlich liegt es an der y-Koordinate die sich dann immer ändert, was muss nun geändert werden damit diese noch von der Zeilenhöhe y richtig bearbeitet wird?

    Als Prompt hab ich mal eine lange bereitgestellt damit man nicht so lange Texte schreiben muss:

    Prompt in("#############################################################:\\>");
    


  • Kann mir niemand weiterhelfen ?????


Anmelden zum Antworten