Zeile löschen
-
Hi, mein Programm liest eine .c in eine Struktur ein:
typedef struct foo { char sZ[255][100]; }St; St Zeilen;
Das klappt auch, liegt schön zeilenweise da drin. Jetzt will ich in der nächsten Funktion jede Zeile davon auslesen und überprüfen, ob darin die Wörter (void int float double char) vorkommen. Wenn ja, bleibt die Zeile unverändert. Wenn aber nix davon drin ist, dann soll die Zeile gelöscht werden alle weiteren eine Stelle nach vorn rücken, also die Zeile weg ebend.
Habe da aber ein Problem! Zum ersten scheint er !manchmal! Zeichen wie { zu überspringen, dann sieht er das "} St;" irgendwie nicht... usw.
Hier die Funktion dazu:
void Zeilen_kuerzen() { char iVergleich=0; char *cfound=0; char sBuffer[100]; char sVariable[5][10]={ {"void"}, {"int"}, {"float"}, {"double"}, {"char"} }; int i=0, j=0, k=0; for(j=0;j<iZeilenanzahl;j++)//Zeilenanzahl beim lesen der Datei ermittelt { printf("%s", Zeilen.sZ[j]);//Testausgabe for(k=0;k<=4;k++)//5x da 5 Var.typen { cfound=strstr(Zeilen.sZ[j], sVariable[k]);//vergleicht, ob der Var. Typ in der Zeile steht iVergleich=iVergleich + cfound;//da haperts if(k==4 && iVergleich!=0)//wenn nach dem 5. Durchgang keine der Var. typen gefunden wurde, ins if gehen { for(i=j;i<iZeilenanzahl;i++) { strcpy(sBuffer, Zeilen.sZ[i+1]);//Kopier nächste Zeile in sBuffer strcpy(Zeilen.sZ[i], sBuffer);//Schreib sBuffer in aktuelle Zeile } } } } }
Nun wollte ich, da ja cfound 0 als zugewiesene Adresse hat, wenn nix gefundn wurde, den Vergleich erhöhen. Aber geht nicht, und ich weiss nicht, wie ich das hin bekommen kann!
Oder findet jemand ne andre, bessere Lösung raus? Wo man dann auch noch weitere Variablentypen ohne riesige probleme hinzufügen kann?
Als .c Datei les ich eine erstellte Kopie dieses Programms hier aus.
-
Die überflüssigen Zeilen "rausschmeißen" kannst du mit C-Mitteln nicht machen (für C++ würde ich eine list<> empfehlen), du kannst sie höchstens in Leerstrings umwandeln, indem du "Zeilen.sZ[i][0]='\0';" setzt. Alternativ kannst du auch nur die gültigen Zeilen in ein zweites Array übertragen.
Das nächste: man: strstr liefert einen Pointer auf die gefundene Position, da bricht deine ganze Arithmetik zusammen ("iVergleich+cFound" ergibt eine Adresse, keinen int-Wert), da mußt du die Überprüfung schon mit if() machen:
int gefunden=0; for(int i=0;i<5;++i) if(strstr(...) gefunden=1; if(!gefunden) // lösche Zeile
-
So wie ich das sehe, lässt du das 5x durchlaufen.
Bei jedem Mal prüft er, ob er etwas gefunden hat, wobei ich da nicht durch sehe, im ersten if fehlt ein ), weiterhin wird if nicht mit ; beendet.Außerdem, wozu das 2. if? Du nutzt kein {, daher führt er nur die Zeile nach dem if aus, aber da du ja schon airgendwie prüfst, ob gefunden=1 ist, kann gefunden doch nicht NULL sein!
Habe jetzt noch kurz was geändert, es müsste gehen, ich weiss nur nicht warum!
void Zeilen_kuerzen() { char *cfound=0; char sBuffer[100]; char sVariable[5][10]={ {"void"}, {"int"}, {"float"}, {"double"}, {"char"} }; int i=0, j=0, k=0; for(j=0;j<iZeilenanzahl;j++) { for(k=0;k<=4;k++) { cfound=strstr(Zeilen.sZ[j], sVariable[k]); if(k==4 && cfound==NULL) { for(i=j;i<iZeilenanzahl;i++) { printf("i=%i\n", i); strcpy(sBuffer, Zeilen.sZ[i+1]); printf("Quelle: |%s|\nZiel:|%s|\n", Zeilen.sZ[i], sBuffer); strcpy(Zeilen.sZ[i], sBuffer); } } } } for(i=0;i<iZeilenanzahl;i++) { printf("%s", Zeilen.sZ[i]); } }
Das Problem ist auch j! Habe vor die 3. for Schleife ne Ausgabe für j gemacht und naja, am Anfang steht da: 0, 1 dann keine 2, weiter mit 3! Warum weiss ich auch nicht -.- Aber hab nachgesehn, in der .c steht in der 3. Zeile das
typedef struct foo
wieso springt er da nicht in das if? Keins der gesuchten Wörter ist da drin!
Das ist anscheinend der große Fehler, denn dann könnten die strcpy ja funktionieren.p.s. das "löschen" der Zeilen ist doch an sich leicht:
Zeile 6 soll weg. Schreibe Zeile 7 in Buffer und Buffer in Zeile 6. Dann Zeile 8 in 7 usw.
-
Diamond schrieb:
So wie ich das sehe, lässt du das 5x durchlaufen.
Bei jedem Mal prüft er, ob er etwas gefunden hat, wobei ich da nicht durch sehe, im ersten if fehlt ein ), weiterhin wird if nicht mit ; beendet.Genau, wenn du das noch optimieren willst, kannst du ja schreiben:
int gefunden=0; for(int i=0;gefunden||i<5;++i) if(strstr(...)) gefunden=1; if(!gefunden) // lösche Zeile
int gefunden=0; for(int i=0;i<5;++i) if(strstr(...)){gefunden=1;break;} if(!gefunden) // lösche Zeile
Außerdem, wozu das 2. if? Du nutzt kein {, daher führt er nur die Zeile nach dem if aus, aber da du ja schon airgendwie prüfst, ob gefunden=1 ist, kann gefunden doch nicht NULL sein!
Nein. In der Schleife überprüfe ich, ob das gerade aktuelle Wort vorkommt und setze im Ernstfall "gefunden" auf 1. Wenn alle Tests negativ gelaufen sind, steht am Schleifenende "gefunden" noch auf 0 (Startwert) und die Bedingung "if(!gefunden)" wird wahr.
Habe jetzt noch kurz was geändert, es müsste gehen, ich weiss nur nicht warum!
for(k=0;k<=4;k++) { cfound=strstr(Zeilen.sZ[j], sVariable[k]); if(k==4 && cfound==NULL) { // Löschschleife } }
Das Problem ist auch j! Habe vor die 3. for Schleife ne Ausgabe für j gemacht und naja, am Anfang steht da: 0, 1 dann keine 2, weiter mit 3! Warum weiss ich auch nicht -.- Aber hab nachgesehn, in der .c steht in der 3. Zeile das
typedef struct foo
wieso springt er da nicht in das if? Keins der gesuchten Wörter ist da drin!Dein Fehler ist die Bedingung: Du prüfst nach, ob k=4 UND cFound=NULL ist - also springt das if() immer dann an, wenn in der Zeile dein fünftes Suchwort ("char")nicht vorkommt.
p.s. das "löschen" der Zeilen ist doch an sich leicht:
Zeile 6 soll weg. Schreibe Zeile 7 in Buffer und Buffer in Zeile 6. Dann Zeile 8 in 7 usw.Mach's doch noch einfacher:
for(i=j;i<Zeilenanzahl-1;++i) strcpy(Zeilen[i],Zeilen[i+1]) Zeilenanzahl--;
PS: du solltest vielleicht ein "#define NUM_KEYS 5" verwenden, statt die "4" überall im Programm hart einzuarbeiten