Wie an bestimmte Position im String navigieren?
-
Hallo, der folgenden Code besteht aus einer Eingabe mit einer Prompt, hierfür wurde getch() verwendet um auf spezielle Tastutur Anschläge zu reagieren, wie z.B.:
Enter = neue Zeile
Backspace = lösche das letzte Zeichen
ESC = lösche den ganzen InputNun schaffe ich es nicht mit den Pfeiltasten, an eine bestimmte Position im Input string zu gelangen, habe es mit gotoxy probiert, aber ich glaub hier wird nur die Ausgabe geändert aber nicht der string.
Noch ein Problem, wenn ich Backspace ausklammer dann versuche den String zu verschieben wird dieser dann in der Console überschrieben, deshalb muss ich Backspace selbst definieren, eigentlich ganz einfach da ja nur ein leere insert(' ') integriert wird, aber die Position wieder

Hoffe ihr könnt mir weiterhelfen.
#include <windows.h> #include <string> #include <iostream> #include <fstream> #include <tchar.h> #include <conio.h> using namespace std; #pragma comment(lib, "User32.lib") void clear_line( string::size_type length, const string &prompt ) { cout.put( '\r' ); for( string::size_type i = 0; i < ( length + prompt.length( ) ); ++i ) { cout.put( ' ' ); } cout << '\r' << prompt << flush; } void gotoxy(short x, short y) { HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(hCon, pos); } int main( ) { bool do_exit = false; const char prompt[ ] = ":\\>"; HANDLE std_output = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info; do { string input; int key; cout << prompt; do { key = _getch( ); //Backspace - Löschen if( ( key == 0x08 ) && input.length( ) ) { clear_line( input.length( ), prompt ); if(input.length() != 0) input.erase( input.length( ) - 1, 1 ); cout << input << flush; } /* //Leertaste else if( key == 0x20) { input.insert(" "); } */ //Escape - ESC else if( key == 0x1b ) { clear_line( input.length( ), prompt ); input = ""; } //Steuerzeichen else if( key == 0xe0 ) { switch( _getch( ) ) { int x, y; case 0x4B: // Pfeiltaste nach Links GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); x = console_screen_buffer_info.dwCursorPosition.X; y = console_screen_buffer_info.dwCursorPosition.Y; gotoxy(x-1, y); break; case 0x4D: // Pfeiltaste nach Rechts GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); x = console_screen_buffer_info.dwCursorPosition.X; y = console_screen_buffer_info.dwCursorPosition.Y; gotoxy(x+1, y); break; } } else if( key != '\r' ) { input += key; cout.put( key ); } }while( key != '\r' ); // enter cout.put( '\n' ); if( input.length( ) ) { cout << "Input: " << input << endl << endl; } if( input == "exit" ) { do_exit = true; } } while( !do_exit ); }
-
Du mußt dir vermutlich die Position in der Zeile merken und dann bei den normalen Eingaben an dieser Position Zeichen einfügen bzw. überschreiben.
PS: Diese längliche if-else-Kaskade kannst du auch als switch() schreiben - ist mit Sicherheit übersichtlicher (und vermutlich sogar schneller).
-
Du mußt dir vermutlich die Position in der Zeile merken und dann bei den normalen Eingaben an dieser Position Zeichen einfügen bzw. überschreiben.
Und wie mache ich das?

-
Zum Merken brauchst du eine einfache int-Variable - Pfeil rechts und die "normalen" Eingabetasten erhöhen den Wert, Pfeil links und Backspace verringern den Wert. Und bei der Eingabe kannst du noch auswählen zwischen Überschreiben und Einfügen:
//Überschreiben: if(textpos<input.length()) input[textpos]=key; else input+=key; //Einfügen: input.insert(textpos,key);
-
Habs überarbeitet:
do { string input; int key; int textpos = 0; cout << prompt; do { key = _getch( ); //Backspace - Löschen if( ( key == 0x08 ) && input.length( ) ) { textpos--; clear_line( input.length( ), prompt ); if(input.length() != 0) input.erase( input.length( ) - 1, 1 ); cout << input << flush; } //Leertaste else if( key == 0x20) { //clear_line( input.length( ), prompt ); input.insert(textpos, " "); cout << input << flush; } //Escape - ESC else if( key == 0x1b ) { textpos = 0; clear_line( input.length( ), prompt ); input = ""; } //Steuerzeichen else if( key == 0xe0 ) { switch( _getch( ) ) { int x, y; case 0x4B: // Pfeiltaste nach Links GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); x = console_screen_buffer_info.dwCursorPosition.X; y = console_screen_buffer_info.dwCursorPosition.Y; gotoxy(x-1, y); textpos--; break; case 0x4D: // Pfeiltaste nach Rechts GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); x = console_screen_buffer_info.dwCursorPosition.X; y = console_screen_buffer_info.dwCursorPosition.Y; gotoxy(x+1, y); textpos++; break; } } else if( key != '\r' ) { string tmp; if(textpos < input.length()) { tmp = key; input.insert(textpos, tmp); cout.put( key ); textpos++; } else { input += key; cout.put( key ); textpos++; } } }while( key != '\r' ); // enter cout.put( '\n' ); if( input.length( ) ) { cout << "Input: " << input << " -> " << textpos << endl << endl; } if( input == "exit" ) { do_exit = true; } } while( !do_exit );Wenn ich nun mit den Pfeilen arbeite und dann was im string reinschreibe wird die Änderung aber nicht in der Console angezeigt, gleiches gilt für Backspace.
Gibt es eine andere Möglichkeit den Cursor zu verschieben ohne WinAPI wgen dem gotoxy dieser überschreibt immer meine Prompt

-
Ohne gotoxy() kannst du du Cursor-Position nicht wirklich steuern, also wirst du da nicht drumherum kommen. Was du Ausgaben angeht, mußt du beim Einfügen und Löschen (btw wäre es eine gute Idee, auch beim Löschen an der aktuellen Textposition anzusetzen) zumindest den hinteren Teil des Strings neu schreiben.
PS: Und ich finde immer noch, daß ein switch(key)... übersichtlicher wäre als deine if-else-Kaskade

PPS: Die Enter-Taste ist übrigens '\n'

-
Habe ein Problem, ich bekomme es nicht hin eine Bedingung aufzustellen wenn man nach die linke Pfeiltaste drückt, dieser solange nach links gehen darf bis zum Promt ende.
Hier erstmal mein Teil für den Rechtsklick, hier darf der Cursor nur bis zum ende der Eingabe gehen:
case 0x4D: // Pfeiltaste nach Rechts: GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); x = console_screen_buffer_info.dwCursorPosition.X; y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos < input.length() + prompt.length()) { textpos++; gotoxy(textpos, y); }Habe es auch für Links versucht, doch meine Bedingung ist falsch:
case 0x4B: // Pfeiltaste nach Links GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); x = console_screen_buffer_info.dwCursorPosition.X; y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos > prompt.length()) { textpos--; gotoxy(textpos, y); } break;Habe nun beim Backspace ein textpos-- eingefügt.
Wenn ich nun nach links gehe und in ein bestehenden string etwas reinschreibe wird der string in der ausgabe nicht nach vorne vorgerückt, damit meine ich die alte ausgabe wird von der neuen überschrieben, wie kann man das verhindern?
-
kernel64 schrieb:
Habe ein Problem, ich bekomme es nicht hin eine Bedingung aufzustellen wenn man nach die linke Pfeiltaste drückt, dieser solange nach links gehen darf bis zum Promt ende.
Hier erstmal mein Teil für den Rechtsklick, hier darf der Cursor nur bis zum ende der Eingabe gehen:
case 0x4D: // Pfeiltaste nach Rechts: GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); x = console_screen_buffer_info.dwCursorPosition.X; y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos < input.length() + prompt.length()) { textpos++; gotoxy(textpos, y); }Habe es auch für Links versucht, doch meine Bedingung ist falsch:
case 0x4B: // Pfeiltaste nach Links GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); x = console_screen_buffer_info.dwCursorPosition.X; y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos > prompt.length()) { textpos--; gotoxy(textpos, y); } break;Die unterste Grenze für die Textposition ist 0, die oberste input.length() (es ist besser, wenn du dich bei der Position auf den Eingabestring beziehst, sonst fügst du die Daten noch an der falschen Stelle ein).
Wenn ich nun nach links gehe und in ein bestehenden string etwas reinschreibe wird der string in der ausgabe nicht nach vorne vorgerückt, damit meine ich die alte ausgabe wird von der neuen überschrieben, wie kann man das verhindern?
Du mußt nicht nur das neu eingegebene Zeichen schreiben, sondern auch alles, was nach der Einfügestelle kam, neu ausgeben (um eine Stelle nach hinten versetzt).
-
So nun hab ichs geschafft, habe auch versucht es mit einer Switch-Anweisung zu machen, doch da bekomme ich seltsame Reaktionen auf Tasten, musste dann wieder mein altes nehmen
will es auch lieber mit switch machen.Bei der clearLineAt() wird alles gelöscht ab der Prompt bis zum Fensterende, hierfür habe ich die Funktion von Improved Console verwendet zum ermitteln der Fensterbreite.
#include <windows.h> #include <string> #include <iostream> #include <conio.h> #include "ic.hpp" //Improved Console using namespace std; using namespace ic; // Auflösen des Improved Console-Namespace #pragma comment(lib, "User32.lib") 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 << '\r' << prompt << flush; } void gotoxy(short x, short y) { HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(hCon, pos); } int main( ) { bool do_exit = false; string prompt = ":\\>"; HANDLE std_output = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info; do { string input; int key, y; int textpos = 0; cout << prompt; do { key = _getch( ); //Backspace - Löschen if( ( key == 0x08 ) && input.length( ) ) { clearLineAt( prompt ); if(textpos > 0) { input.erase(textpos-1, 1 ); cout << input << flush; GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; int currentPosition = prompt.length() + textpos; gotoxy(currentPosition-1, y); textpos--; } } //Leertaste else if( key == 0x20) { clearLineAt( prompt ); input.insert(textpos, " "); cout << input << flush; GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; int currentPosition = prompt.length() + textpos; gotoxy(currentPosition+1, y); textpos++; } //Escape - ESC else if( key == 0x1b ) { textpos = 0; clearLineAt( prompt ); input = ""; } //Steuerzeichen else if( key == 0xe0 ) { switch( _getch( ) ) { int x, y; case 0x4B: // Pfeiltaste nach Links GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos > 0) { int currentPosition = prompt.length() + textpos; gotoxy(currentPosition-1, y); textpos--; } break; case 0x4D: // Pfeiltaste nach Rechts: GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos < input.length()) { int currentPosition = prompt.length() + textpos; gotoxy(currentPosition+1, y); textpos++; } break; case 0x53: //Entfernen Taste 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; int currentPosition = prompt.length() + textpos; gotoxy(currentPosition, y); } break; } } else if( key != '\r' ) { string tmp; GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos < input.length()) { clearLineAt( prompt ); tmp = key; input.insert(textpos, tmp); //cout.put( key ); cout << input << flush; } else { input += key; cout.put( key ); } int currentPosition = prompt.length() + textpos; gotoxy(currentPosition+1, y); textpos++; } }while( key != '\r' ); // enter cout.put( '\n' ); if( input.length( ) ) { cout << "Input: " << input << " -> " << textpos << endl << endl; } if( input == "exit" ) { do_exit = true; } } while( !do_exit ); }Es ist mir aufefallen wenn ich mit der Backspace Taste alles lösche in nix mehr da steht bewegt sich der Cursor am Anfang der Prompt hin und her _<->_ einmal bei textpos=0 und textpos=1 woran liegt das?
So jetzt habe ich ein Grundgerüst erstellt, damit kann ich fast weiterarbeiten, was kann man noch verbessern, optimieren am Code?
Wenn man sich die cmd hierzu anschaut da sehe ich kein Flackern bei der Prompt, wird diese nicht überschrieben wie bei mir und wie kann man das verhindern?
-
@switch: Hast du auch daran gedacht, jeden einzelnen Zweig mit break; zu beenden?
@Flackern: Vermutlich überschreibt die normale Konsole nur die Zeichen, die sich tatsächlich geändert haben (du überschreibst erst die komplette Zeile mit Leerzeichen, bevor du deine Ausgabe drübersetzt).
-
Habs nochmal in Switch umgewandelt, doch es sind ganz andere Aktionen auf die Tasten und bei der Ausgabe.
do { key = _getch( ); switch(key) { case 0x08: //Backspace clearLineAt( prompt ); if(textpos > 0) { input.erase(textpos-1, 1 ); 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 0x20: //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 0x1b: //ESC textpos = 0; clearLineAt( prompt ); input = ""; break; case 0xe0: //Steuerzeichen switch( _getch( ) ) { int x, y; case 0x4B: // Pfeiltaste nach Links GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos > 0) { currentPosition = prompt.length() + textpos; gotoxy(currentPosition-1, y); textpos--; } break; case 0x4D: // Pfeiltaste nach Rechts: GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos < input.length()) { currentPosition = prompt.length() + textpos; gotoxy(currentPosition+1, y); textpos++; } break; case 0x53: //Entfernen Taste 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; } if( key != '\r' ) { string tmp; GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos < input.length()) { clearLineAt( prompt ); tmp = key; input.insert(textpos, tmp); //cout.put( key ); cout << input << flush; } else { input += key; cout.put( key ); } currentPosition = prompt.length() + textpos; gotoxy(currentPosition+1, y); textpos++; } }while( key != '\r' ); // enterWenn ich nun die Pfeiltasten verwende, kommen unbekannte Zeichen in der Ausgabe und Backspace funktioniert nicht, bei Leerzeichen wird eine zuviel freigelassen...
-
Erstmal kannst du auch den Abschnitt "if(key!='\r')..." in den switch mit reinziehen (als default:-Zweig) - und die Behandlung des Leerzeichens stimmt (vermutlich) mit allen anderen "Normaltasten" überein, benötigt also auch keine Sonderbehandlung.
(und das 'int x,y;' im inneren switch-Block sieht zumindest seltsam aus)
PS: Und anstelle von '\r' solltest du lieber '\n' als Endekriterium der Schleife verwenden

-
Hab nun den if Teil in default reingepackt:
default: string tmp; GetConsoleScreenBufferInfo( std_output, &console_screen_buffer_info ); y = console_screen_buffer_info.dwCursorPosition.Y; if(textpos < input.length()) { clearLineAt( prompt ); tmp = key; input.insert(textpos, tmp); //cout.put( key ); cout << input << flush; } else { //cout << "TEST" << endl; input += key; cout.put( key ); } currentPosition = prompt.length() + textpos; gotoxy(currentPosition+1, y); textpos++;Jetzt ist mir aufgefallen wenn ich nix eingebe dann wird außerhalb der Scheife if( input.length( ) ) d.h. input wurde gefüllt, deshalb habe ich eine Test Ausgabe oben in dem else Teil eingebaut und wie man sieht wird diese aufgerufen. Es wird immer ein Zeichen zuviel eingefügt, ich kann z.b. das programm mit exit nicht mehr beenden, außerdem wird gesagt das die Länge = 5 ist.
Habe auch bei der While-Schleife '\n' eingefügt nun wird aber keine neue Zeile erstellt, muss ich nun auch eine Funktion für ENTER einbauen?
-
kernel64 schrieb:
Jetzt ist mir aufgefallen wenn ich nix eingebe dann wird außerhalb der Scheife if( input.length( ) ) d.h. input wurde gefüllt, deshalb habe ich eine Test Ausgabe oben in dem else Teil eingebaut und wie man sieht wird diese aufgerufen. Es wird immer ein Zeichen zuviel eingefügt, ich kann z.b. das programm mit exit nicht mehr beenden, außerdem wird gesagt das die Länge = 5 ist.
Und was heißt das auf deutsch?
PS: string::insert() kann auch einzelne Zeichen Zeichen einfügen:
input.insert(textpos,1/*Anzahl*/,key/*Wert*/);
-
OK jetzt bin ich fertig dank deiner Hilfe
Wie gut das es dich gibt 
#include <windows.h> #include <string> #include <iostream> #include <conio.h> #include "ic.hpp" //Improved Console #pragma comment(lib, "User32.lib") using namespace std; using namespace ic; // Auflösen des Improved Console-Namespace #define ENTER 13 #define BACKSPACE 8 #define LEERTASTE 32 #define ESCAPE 27 #define STEUERZEICHEN 224 #define PFEIL_LINKS 75 #define PFEIL_RECHTS 77 #define DELETE 83 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; } void gotoxy(short x, short y) { HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(hCon, pos); } int main( ) { bool do_exit = false; string prompt = ":\\>"; HANDLE std_output = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info; do { string input; int key, currentPosition, y; int textpos = 0; cout << prompt; do { key = _getch( ); switch(key) { case BACKSPACE: //Backspace clearLineAt( prompt ); if(textpos > 0) { input.erase(textpos-1, 1 ); 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 ENTER: //Enter == '\r' cout << "ENTER" << endl; input.append("\0"); //textpos = 0; break; case LEERTASTE: //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: //ESC textpos = 0; clearLineAt( prompt ); input = ""; break; case STEUERZEICHEN: //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: //Entfernen Taste 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; 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++; }//Switch() }while( key != ENTER ); // enter cout << endl; if( input.length( ) ) { cout << "Input: " << input << " -> " << textpos << endl << endl; } if( input == "exit" ) { do_exit = true; } } while( !do_exit ); }Noch eine kleine Hilfe bräuchte ich, das Flackern ärgert mich immernoch, ich weiß das die ganze Zeile gelöscht wird, doch wenn ich z.b. die cout << "\r" auslase, wird die Ausgabe versetzt ausgegeben, was sollte ich nun machen damit die Prompt nur einmal ausgegeben wird bzw. nicht mehr flackert?
-
Das Flackern kommt daher, daß du erst die komplette Zeile mit Leerzeichen überschreibst und anschließend deine (geänderte) Eingabe darüber schreibst - dazwischen liegen zwar nur einige Mikosekunden, aber trotzdem macht sich das bemerkbar. Die einfachste Lösung ist es wohl, nur den mit Leerzeichen zu überschreiben, der auch tatsächlich leer werden soll (das bedeutet: bei ESC die komplette Eingabe, bei Backspace und Del das letzte Zeichen der Eingabe).
-
OK, ich werds mal versuchen, trotzdem vielen Dank

Gibts vielleicht noch was anderes zu verbesseren?