Ein Zeichen aus einem Char-Array löschen
-
Hallo bin ein Programmieranfänger und hatte erst eine Handvoll Unterichtsstunden. Dennoch habe ich schon ein Problem:
Ich habe ein Array (char=telefon[5][30];) in dem ich 5 Telefonnummern speichere.Nun möchte (oder besser muss
)ich daraus die Sonderzeichen, die evtl. mit eingegeben wurden löschen. Also z.b.: / - usw.
Ich habe mir also gedacht, ich gehe die Telefonnummer Stelle für Stelle durch und prüfe, ob das Zeichen an der jeweiligen Stelle im Bereich der ASCII-Werte der Zahlen 0 bis 9 liegt. (if (telefon[i][j] < '0' || telefon[i][j] > '9') ...)
Das Problem ist nun, ich weiß nicht, wie ich das Zeichen entferne und die restlichen Stellen aufrücke.
Habe überlegt, ob es mit strcpy oder strncpy geht. Funktioniert aber beides nicht. Beifor (x=i; x<29; x++) { strcpy (telefon[j][x], telefon[j][x+1]); }
gibt er mir den Fehler:
error 'strcpy': Konvertierung des Parameters 1 von 'char' in 'char *' nicht möglich
aus.bei
for (x=i; x<29; x++) { y = x+1; strncpy (p.tele[j]+x, p.tele[j]+y, 1); }
passiert nach der Eingabe gar nix mehr, sondern ich fliege direkt raus.
Kann mir jemand erklären, ob ich nur Syntaxfehler habe, oder ob es einen besseren Befehl dafür gibt?
-
nimm memmove - das verschont dich bei überlappenden Speicherbereichen. Oder noch besser: verwende std::string.
-
Also memmove sieht ja schon ganz gut aus...problem:
// Telefonnummern bereinigen // 5 Telefonnummern durchgehen: for (j=0; j<5; j++) { // 30 Zeichen überprüfen: for (i=0; i<30; i++) { // Prüfen, ob das Zeichen an Stelle i kleiner oder größer der ASCII-Werte von 0 bis 9 ist if (p.tele[j][i] < '0' || p.tele[j][i] > '9') { x = i+1; y = 30-i; memmove( p.tele[j]+i, p.tele[j]+x, y); } } }
hat den Erfolg, dass das Programm nach der Eingabe nur noch
Press any key to continue...
anzeigt und nicht die AusgabeHier mal der gesamte Code:
//Alphabetische Sortierung von Namen //(C) by S. Pohlschmidt #include <iostream.h> #include <string.h> #include <stdio.h> #include <memory.h> struct person { char name[5][30], vor[30], nach[30], tele[5][30]; int alter[5]; }; int main() { person p; char merker[30], *tok, *tok2; int i, j, amerk, x,y; for(i=0;i<5;i++) { cout<<endl<<"Geben Sie den " << i+1 << ".ten Namen ein >> "; cin.getline(p.name[i],30); cout<<endl<<"Geben Sie das Alter von "<<p.name[i]<<" ein >> "; cin>>p.alter[i]; cin.ignore(); cout<<endl<<"Geben Sie die Telefonnummer von "<<p.name[i]<<" ein >> "; cin.getline(p.tele[i],30); } // Telefonnummern bereinigen // 5 Telefonnummern durchgehen: for (j=0; j<5; j++) { // 30 Zeichen überprüfen: for (i=0; i<30; i++) { // Prüfen, ob das Zeichen an Stelle i kleiner oder größer der ASCII-Werte von 0 bis 9 ist if (p.tele[j][i] < '0' || p.tele[j][i] > '9') { x = i+1; y = 30-i; memmove( p.tele[j]+i, p.tele[j]+x, y); } } } for(i=0;i<5;i++) { tok= strtok(p.name[i], " "); tok2=strtok(NULL," "); if(tok2!=NULL) { strcpy(p.vor, tok); strcpy(p.nach, tok2); strcpy(p.name[i],p.nach); strcat(p.name[i],", "); strcat(p.name[i],p.vor); } } for(i=0;i<5;i++) { for(j=0;j<5-1;j++) { if((strcmp(p.name[j+1],p.name[j]))<0) { strcpy(merker, p.name[j+1]); strcpy(p.name[j+1], p.name[j]); strcpy(p.name[j], merker); amerk=p.alter[j+1]; p.alter[j+1]=p.alter[j]; p.alter[j]=amerk; strcpy(merker, p.tele[j+1]); strcpy(p.tele[j+1], p.tele[j]); strcpy(p.tele[j], merker); } } } for(i=0;i<5;i++) { cout<<endl<<endl<<"Der "<<i+1<<".te Name lautete "<<p.name[i]<<" und ist "<<p.alter[i]<<" Jahre alt"<<endl; cout<<"Die Telefonnummer lautet: "<<p.tele[i]<<"."<<endl; } return 0; }
-
Ich glaube, ehe du dich an solche Zeiger-Zerlegungen ranwagst, nimm lieber C++ strings für deine Daten (die haben z.B. find(), find_first_of(),... zum Suchen von Zeichen, substr() zum rauskramen von Teilstrings und erase() mit dem man problemlos einzelne Teile löschen kann - und die eingegebenen Daten können beliebig lang werden).
-
Hmm...tja, das Problem ist, dass in der Aufgabe vorgegeben war, ein Array telefon[5][30] zu nutzen.
Außerdem kenne ich mich mit den String befehlen noch gar nicht aus.
kann ich auch aus einem String ein Array machen?string telefon[5][30] ?
-
mit strings wäre das "string telefon[5];" (die Länge verwaltet sich automatisch).
Aber wenn du unbedingt auf char-Arrays arbeiten mußt, empfehle ich die per-Hand-Abarbeitung:int xout=0,xin=0 while(telefon[i][xout]!='\0') { if(isdigit(telefon[i][xout])//hier kannt du auch direkt vergleichen auf t>='0'&&t<='9' { telefon[i][xin]=telefon[i][xout]; ++xin; } ++xout } telefon[i][xin]='\0';
-
Das funktioniert doch so gar nicht, oder?
Also zum einen gibt er mir einen Fehler aus, isdigit sei ein nicht deklarierter Bezeichner und zum anderen:
int xout=0,xin=0 while(telefon[i][xout]!='\0') //Schleife läuft durch bis Telefonnummer zuende, richtig? { if(isdigit(telefon[i][xout])//isdigit ist ein nicht deklariert bezeichner? { telefon[i][xin]=telefon[i][xout]; //ist das nicht falsch? dann setzt er doch z.b. xout = 5 auf xin = 0 falls vorher da eine Zahl war, ist die doch weg? ++xin; } ++xout } telefon[i][xin]='\0';
Vielleicht missverstehen wir uns ja auch...
Ich möchte, dass wenn z.b. eine 01234/56789 eingegeben wird, nachher eine 0123456789 ausgegeben wird...also falls irgendwelche nicht-zahlen drin sind, diese rausfliegen.
Aber wenn ich mit deinem Beispiel überlege, geht er doch hin und wirft alles durcheinander, oder verstehe ich das nur nicht richtig?
-
//Schleife läuft durch bis Telefonnummer zuende, richtig?
Korrekt - '\0' ist die C-Variante zu sagen "hier ist der String zu Ende"
//isdigit ist ein nicht deklariert bezeichner?
include mal <cctype>, dort ist der Bezeichner deklariert. Oder du ersetzt die Bedingung durch "if(telefon[i][xout]>='0'&&Telefon[i][xout]<='9')".
//ist das nicht falsch? dann setzt er doch z.b. xout = 5 auf xin = 0 falls vorher da eine Zahl war, ist die doch weg?
Nein, du überschreibst nicht die Variable xin, sondern das Zeichen an der Position xin.
*rechnet mal ein Beispiel vor*
Eingabe: "012/34" xin xout Text[xout] if-Test Text 0 0 '0' true "012/34" 1 1 '1' true "012/34" 2 2 '2' true "012/34" 3 3 '/' false 3 4 '3' true "012334" 4 5 '4' true "012344" 5 6 '\0' false ->Schleifen-Ende Text[xin]='\0' -> Text="01234"
-
Hell yeah!
So funktioniert es...bis auf einen Haken:
Ich muss in der For-Schleife einen Fehler haben, der überprüft nämlich immer nur die erste eingegebene Telefonnummer...hab ich ein Brett vorm Kopf?
[EDIT]
Jetzt gehts!!! Vielen, vielen Dank für die Hilfe!
[/EDIT]//Alphabetische Sortierung von Namen //(C) by S. Pohlschmidt #include <iostream.h> #include <string.h> #include <stdio.h> #include <cctype> struct person { char name[5][30], vor[30], nach[30], tele[5][30]; int alter[5]; }; int main() { person p; char merker[30], *tok, *tok2; int i, j, amerk; for(i=0;i<5;i++) { cout<<endl<<"Geben Sie den " << i+1 << ".ten Namen ein >> "; cin.getline(p.name[i],30); cout<<endl<<"Geben Sie das Alter von "<<p.name[i]<<" ein >> "; cin>>p.alter[i]; cin.ignore(); cout<<endl<<"Geben Sie die Telefonnummer von "<<p.name[i]<<" ein >> "; cin.getline(p.tele[i],30); } // Telefonnummern bereinigen // 5 Telefonnummern durchgehen: for (i=0; i<5; i++) { int xin=0,xout=0; while(p.tele[i][xout]!='\0') { if(isdigit(p.tele[i][xout]))//hier kannt du auch direkt vergleichen auf t>='0'&&t<='9' { p.tele[i][xin]=p.tele[i][xout]; ++xin; } ++xout; } p.tele[i][xin]='\0'; } for(i=0;i<5;i++) { tok= strtok(p.name[i], " "); tok2=strtok(NULL," "); if(tok2!=NULL) { strcpy(p.vor, tok); strcpy(p.nach, tok2); strcpy(p.name[i],p.nach); strcat(p.name[i],", "); strcat(p.name[i],p.vor); } } for(i=0;i<5;i++) { for(j=0;j<5-1;j++) { if((strcmp(p.name[j+1],p.name[j]))<0) { strcpy(merker, p.name[j+1]); strcpy(p.name[j+1], p.name[j]); strcpy(p.name[j], merker); amerk=p.alter[j+1]; p.alter[j+1]=p.alter[j]; p.alter[j]=amerk; strcpy(merker, p.tele[j+1]); strcpy(p.tele[j+1], p.tele[j]); strcpy(p.tele[j], merker); } } } for(i=0;i<5;i++) { cout<<endl<<endl<<"Der "<<i+1<<".te Name lautete "<<p.name[i]<<" und ist "<<p.alter[i]<<" Jahre alt"<<endl; cout<<"Die Telefonnummer lautet: "<<p.tele[i]<<"."<<endl; } return 0; }