Logikfehler - meine Logik.exe spinnt...
-
Guten Abend,
das ist mein erster Eintrag in diesem Forum und ich bitte zu entschuldigen, dass ich nicht genau weiss, welcher Informationen ich liefern muss um meine Frage korrekt zu stellen. Ich gebe einfach mal mein bestes.
Ich muss fuer die Uni ein Programm schreiben, dass die Telefonkosten einer WG verwaltet. Das ganze geschieht unter Unix. Hierzu werden verschiedene Infos in einem Feld namens call gespeichert, dieses Feld hat 100 Eintraege mit structs namens telefonat, darin sind Angaben wie der Name, das Datum, die Uhrzeit zu der telefoniert wurde, sowie ob Ferngespraech etc.
Mein eigentliches Problem liegt in folgendem Programmabschnitt
/* Funktion zum Loeschen eines einzelnen Monats */ void deletemon(struct telefonat call[100]) { char vergleich[15]="##############"; int c, j, m, k, a, b; int n=0; do { printf(" Welchen Monat moechten Sie loeschen? Geben Sie das Jahr, dann den Monat an!\n\n"); k=1; scanf("%i %i", &j, &m); flushstdin(); if(j>= 1950 && j<=2140 && m>=1 && m<=12) { for( n=0; n<100; n++) {c=strcmp(call[n] .name, vergleich); if(c != 0) { if (call[n] .year == j ) {printf(" Ich hab was gefunden!\n"); if (call[n] .mon == m) { strcpy(call[n] .name, vergleich); do {a=0; b=n+1; c= strcmp(call[b] .name, vergleich); if (c==0 || b==100) {a=1;} else {call[b-1] = call[b]; b++; } } while (a==0); strcpy(call[b-1] .name, vergleich); } else {printf(" CCC");} } else {printf(" BBB");} } else {printf(" AAA");} } k=0; } else {printf(" Falsche Eingabe! Versuchen Sie es bitte erneut!\n\n");} } while( k==0); }
Der eigentliche Sinn ist, dass der Benutzer gesamte Monate loeschen kann. Hierzu wird das Jahr und dann der Monat als Zahl eingegeben. Das Programm geht dann alle Feldeintraege durch.
Wir initialisieren jeden Feld-namen zuerst mit diesen Rauten, das bedeutet sozusagen, dass das Feld leer ist.
Wenn also keine Raute drin steht, dann wird geprueft ob das Jahr passt, wenn das passt, dann soll der Monat ueberprueft werden.
Funktioniert das alles, wird dieser Eintrag geloescht und mit der do-while Schleife ruecken dann alle Eintraege danach eins auf.Dieses "Aufruecken" funktioniert, ebenso gibt es passende Feldeintraege zum Loeschen. Bin mir nicht ganz sicher, ob ich das gesamte Programm posten sollte.
Wenn unser Programm dann laeuft und wir in diesem Fall
2000
5
eingeben, dann folgt vom Programm folgendes:BBB Ich hab was gefunden!
Und dann passiert garnichts mehr.
Ich hoffe, ihr koennt mir helfen. Mein Teampartner und ich finden den Fehler einfach nicht...
Vielen Dank im voraus!
-
Was mir noch aufgefallen ist - der ersten Eintrag in meiner Liste ist aus dem Jahr 2012 - dementsprechend das BBB, der zweite ist aus 2000, deshalb das "Ich hab was gefunden" - danach schmiert er allerdings ab, bzw. macht garnichts mehr.
-
Arrays werden ab 0 indiziert, soll heissen einen array der Größe N hat valide Eintrage von 0 bis N-1 !
Eure for schleife (Zeile 21) läuft bis N-1, in Zeile 37 wird auf call[b] mit b = n+1 zugegriffen, was irgendwann mal N erreicht. Bang.Auch ist die Angabe "es tut nix mehr" oder "schmiert ab" nich sehr präzise (zumal das zwei völlig verschiedene Angelegenheiten sind). Bitte genauer angeben was das Programm macht und welche Fehlermeldungen auftauchen.
-
Vielen Dank für die Hilfe und für das Feedback.
Es gibt keine Fehlermeldungen. Ich würde so etwas einen Laufzeitfehler nennen. Er arbeitet, ich kann weiterhin Sachen im Terminal eintippen, aber es passiert nichts.
Ich habe das Programm jetzt korrigiert
void deletemon(struct telefonat call[100]) { char vergleich[15]="##############"; int c, j, m, k, a, b; int n=0; do { printf(" Welchen Monat moechten Sie loeschen? Geben Sie das Jahr, dann den Monat an!\n\n"); k=1; scanf("%i %i", &j, &m); flushstdin(); if(j>= 1950 && j<=2140 && m>=1 && m<=12) { for( n=0; n<100; n++) {c=strcmp(call[n] .name, vergleich); if(c != 0) { if (call[n] .year == j ) {printf(" Ich hab was gefunden!\n"); if (call[n] .mon == m) {printf(" TEST!\n"); strcpy(call[n] .name, vergleich); printf(" TEST2!\n"); do {a=0; b=n+1; if (b != 100) { c= strcmp(call[b] .name, vergleich); printf(" TEST3!\n"); if (c==0) {a=1;} else {call[b-1] = call[b]; b++; } } else {a=1;} } while (a==0); strcpy(call[b-1] .name, vergleich); } else {printf(" CCC");} } else {printf(" BBB");} } else {printf(" AAA");} } k=0; } else {printf(" Falsche Eingabe! Versuchen Sie es bitte erneut!\n\n");} } while( k==0); }
Beim Start des Programmes und der Eingabe von 2000 und 5, erhalte ich nun unendlich viele "TEST3"s. Der zweite Eintrag entspricht dem Jahr 2000 und dem Mai, also dem Monat 5.
Aus irgendeinem - mir nicht erklärlichen Grund - steckt er permanent in der do-while Schleife fest.Vor allem, da der 2te Eintrag, sprich n=1 mein Programm in die do-while schickt, kann hier der Fehler mit dem b=100 nicht greifen, da ich ja nur einmal die Ausgabe am Anfang "BBB" erhalte.
Das Programm erkennt also das für n=1 die ersten drei if-Abfragen zutreffen, geht in die do-while und kommt nicht mehr heraus
-
Grauenvoller Code.
Zuviel Code für diese einfache Aufgabenstellung, zuviele überflüssige "Hilfs"variablen, und genau da liegt auch das Problem: du hast den Überblick über deine vielen Hilfsvariablen und deren Zuweisungen verloren.
Nutze statt der inneren do/while besser eine for-Schleife.
-
Das b=n+1 in die Schleife zu setzen, war dann leider eine doofe Idee, so hat er immer den gleichen Eintrag überprüft
Nun funktioniert es, seltsamerweise löscht er nicht alle Einträge, die zutreffend sind, aber da such ich nun einfach weiter.Wutz, vielen Dank für den Tipp. Ich bin mir bewusst, dass es schöner geht. Leider programmiere ich erst seit 1-2 Monaten und bin von daher noch nicht so ganz in der Materie.