-
19. 12. 2011, 19:04 #1
[Geloest] [C] Problem bei Stringübergabe an Funktion
Ich habe heute nochmal ein Programm neukompiliert was ich schon länger geschrieben hatte und plötzlich funktioniert es nicht mehr. Ich bin schon mit dem Visual Studio debugger drübergelaufen und meine den Fehler identifiziert zu haben, ich habe jedoch leider keine Ahnung wie ich ihn beheben kann. Ich würde mich über eine Antwort freuen!
Der Fehler liegt bei der Übergabe des Pfades an die Funktion readSudoku(char *path, char** faeld);
Es äußert sich wie folgt: ich übergebe den gesamten Pfad an die Funktion, die Funktion erhält jedoch immer nur den ersten Char des Strings...
Hauptroutine:
hier die Funktion:Code:int main(int argc, char *argv[]){ char** faeld; int loesungen=0; char pfad[200]; char i; pfad[0]='\0'; //Leert den String faeld=(char**)malloc(9*sizeof(char)); for(i=0;i<10;i++) faeld[i]=(char*)malloc(9*sizeof(char)); if(argc>1){ strcat(pfad, argv[1]); } else { printf("Bitte geben Sie den Pfad zum zu loesenden Sudoku an:\n"); scanf("%s",pfad); } if(readSudoku(pfad, faeld) < 0) return 0; printf("Urspruengliches Sudoku:\n"); printSudoku(faeld); printf("\n"); loesen(0, 0, pfad, &loesungen, faeld); //Beginne mit der Lösung /*Loesung abgeschlossen*/ printf("Loesungen: %d\n", loesungen); if(loesungen==0) writeError(pfad); free(faeld); return 0; }
Edith meint dass eine kleine Änderung vorgenommen wurde:Code:int readSudoku(char *path, char** faeld) { FILE *datei; int a, b; char ipbuffer[12] = {0}; if((datei = fopen(path, "r")) == NULL) { printf("Datei nicht gefunden!\n"); writeError(path); return -1; } for(a = 0; a < 9; a++) { if(fgets(ipbuffer, 12, datei) == NULL) { printf("Datei zu kurz!\n"); writeError(path); fclose(datei); return -1; } for(b = 0; b < 9; b++) { if(((ipbuffer[b] - '0') < 0 || (ipbuffer[b] - '0' > 9)) && !(ipbuffer[b] - '0' == -16)){ printf("Eingabefehler!\n"); writeError(path); fclose(datei); return -1; } else { faeld[a][b] = ipbuffer[b] - '0'; } } } fclose(datei); return 0; }
Früher war die Variable "faeld" eine Variable namens "feld" die nicht mit malloc sondern per Hand global als "char feld[9][9]" deklariert wurde!
Oha noch ne Edith will dass ich den ganzen Code hier poste...
Spoiler:
Code:/* Aufgaben: Geschickte Datenstrukturen [x] Wenige Call by Value [x] Wenige globals [x] Eingabe per form. Textdatei[x] Kommandozeilenparameter [x] Dateifehler abfangen [x] Linux - GCC [x] Prototypen + Beschreibung [x] Namensgebung [x] Eingabefehlerausgabe [x] */ /* Bedienungsanleitung: Der Sudokulöser lässt sich starten per Doppelklick, indem man ihn in die Kommandozeile zieht, oder indem man das zu lösende Sudoku direkt auf die .exe per drag&drop schiebt. Wird es per Kommandozeile aufgerufen gibt es 2 Möglichkeiten: Man kann bevor das Programm ausgeführt wird den Pfad zum zu lösenden Sudoku mit Leerzeichen getrennt angeben: "37843-sudoku.exe pfad\zum\sudoku.file" oder das Programm direkt aufrufen und nachträglich den Pfad zum Sudoku angeben: "37843-sudoku.exe Bitte geben Sie den Pfad zum zu loesenden Sudoku an: pfad\zum\sudoku.file" Alternativ, wenn das File im selben Ordner wie das Programm liegt, muss nicht der gesamte Pfad angegeben werden, sondern lediglich der Dateiname. Wird nun per Returntaste bestätigt, wird das Lösungsprogramm in Gang gesetzt. Der Löser wird alle gefundenen Lösungen in der Kommandozeile ausgeben, die erste gefundene Lösung wird zudem in ein Textfile namens "sudoku-geloest.txt" geschrieben. Liegt ein Eingabefehler vor, schreibt das Programm "Eingabefehler" in die sudoku-geloest.txt". */ /*Includes*/ #include <stdio.h> #include <string.h> #include <stdlib.h> /*Constants*/ /*Globals*/ //static char feld[9][9]; /*Prototypes*/ int readSudoku(char *path, char** faeld); //Liest das Sudoku aus einer Datei ein void printSudoku(char** faeld); //Gibt das Sudoku in der Kommandozeile aus int allePruefen(int x, int y, int wert, char** faeld); //Prüft die Integrität der Werte, ruft andere Prüfungsfunktionen auf int xAchsePruefen(int y, int wert, char** faeld); //Prüft die Waagrechte Integrität int yAchsePruefen(int x, int wert, char** faeld); //Prüft die Vertikale Integrität int boxPruefen(int x, int y, int wert,char** faeld); //Prüft die Integrität in der jeweiligen Box int loesen(int x, int y, char *pathptr, int *lsptr, char** faeld); //Rekursiver Lösungsalgorithmus int writeSudoku(char *ptr, char** faeld); //Gibt gelöstes Sudoku in Datei aus int writeError(char *ptr); //Gibt Fehlermeldung in Datei aus /*Main Routine*/ int main(int argc, char *argv[]){ char pfad[200]; char** faeld; int loesungen=0; char asdfblub; pfad[0]='\0'; faeld=(char**)malloc(9*sizeof(char)); for(asdfblub=0;asdfblub<10;asdfblub++) faeld[asdfblub]=(char*)malloc(9*sizeof(char)); //Leert den String if(argc>1){ strcat(pfad,argv[1]); } else { printf("Bitte geben Sie den Pfad zum zu loesenden Sudoku an:\n"); scanf("%s",pfad); } if(readSudoku(pfad, faeld) < 0) return 0; printf("Urspruengliches Sudoku:\n"); printSudoku(faeld); printf("\n"); loesen(0, 0, pfad, &loesungen, faeld); //Beginne mit der Lösung /*Loesung abgeschlossen*/ printf("Loesungen: %d\n", loesungen); if(loesungen==0) writeError(pfad); free(faeld); return 0; } /*Functions*/ int loesen(int x, int y, char *pathptr, int *lsptr, char** faeld) { int i; if(x == 9) { // Zeilenende erreicht y++; x = 0; if(y == 9) // Ende des Sudokufeldes erreicht return 1; } if(faeld[y][x] > -16 && faeld[y][x] > 0) // Feld schon gesetzt return loesen(x+1, y, pathptr, lsptr, faeld); // Nächstes Feld for(i = 1; i <= 9; i++) { // Keine Zahl if(!allePruefen(x, y, i, faeld)) { // Integrität prüfen faeld[y][x] = i; // Falls Zahl passt einsetzen if(loesen(x+1, y, pathptr, lsptr, faeld)) { // Nächstes Feld *lsptr=*lsptr+1; // Lösung gefunden if(*lsptr < 2){ writeSudoku(pathptr, faeld); //Erste Lösung in Datei schreiben } printf("Loesung %d:\n", *lsptr); printSudoku(faeld); printf("\n"); } } } faeld[y][x] = -16; // Keine Zahl hat gepasst, Feld wird wieder auf ' ' gesetzt return 0; } int readSudoku(char *path, char** faeld) { FILE *datei; int a, b; char ovw[200]; char ipbuffer[12] = {0}; ovw[0]='\0'; strcat(ovw,path); if((datei = fopen(ovw, "r")) == NULL) { printf("Datei nicht gefunden!\n"); writeError(path); return -1; } for(a = 0; a < 9; a++) { if(fgets(ipbuffer, 12, datei) == NULL) { printf("Datei zu kurz!\n"); writeError(path); fclose(datei); return -1; } for(b = 0; b < 9; b++) { if(((ipbuffer[b] - '0') < 0 || (ipbuffer[b] - '0' > 9)) && !(ipbuffer[b] - '0' == -16)){ printf("Eingabefehler!\n"); writeError(path); fclose(datei); return -1; } else { faeld[a][b] = ipbuffer[b] - '0'; } } } fclose(datei); return 0; } void printSudoku(char** faeld) { int i, j; for(i = 0; i < 9; i++) { for(j = 0; j < 9; j++) { if(faeld[i][j]==-16) printf(" "); else printf("%d", faeld[i][j]); } printf("\n"); } } int allePruefen(int x, int y, int wert, char** faeld) { if((xAchsePruefen(y, wert, faeld)+yAchsePruefen(x, wert, faeld)+boxPruefen(x, y, wert, faeld))>0) return 1; return 0; } int xAchsePruefen(int y, int wert, char** faeld) { int i; for(i = 0; i < 9; i++) if(faeld[y][i] == wert) return 1; return 0; } int yAchsePruefen(int x, int wert, char** faeld) { int i; for(i = 0; i < 9; i++) if(faeld[i][x] == wert) return 1; return 0; } int boxPruefen(int x, int y, int wert, char** faeld) { int xb, yb, i, j; xb = (int)(x / 3) * 3; yb = (int)(y / 3) * 3; for(i = yb; i < yb + 3; i++) for(j = xb; j < xb + 3; j++) if(faeld[i][j] == wert) return 1; return 0; } int writeSudoku(char *ptr, char** faeld) { FILE* datei; int x, y; char *ptr1; if(strrchr(ptr,92)==NULL){ datei=fopen("sudoku_geloest.txt","w+"); if(datei==NULL){ return -1; printf("Fehler beim schreiben der Datei!"); } for(x=0; x<9; x++){ for(y=0; y<9; y++){ fprintf(datei, "%c",(faeld[x][y]+48)); } if(!(x==8)) fprintf(datei, "\n"); } fclose(datei); } else { ptr1 = strrchr(ptr,92); ptr1=ptr1+1; *ptr1='\0'; datei=fopen(strcat(ptr,"sudoku_geloest.txt"),"w+"); if(datei==NULL){ return -1; printf("Fehler beim schreiben der Datei!"); } for(x=0; x<9; x++){ for(y=0; y<9; y++){ fprintf(datei, "%c",(faeld[x][y]+48)); } if(!(x==8)) fprintf(datei, "\n"); } fclose(datei); } return 0; } int writeError(char *ptr){ FILE* datei; char *ptr1; if(strrchr(ptr,92)==NULL){ datei=fopen("sudoku_geloest.txt","w+"); if(datei==NULL){ return -1; printf("Fehler beim Schreiben der Datei!"); } fprintf(datei,"Eingabefehler"); fclose(datei); } else { ptr1 = strrchr(ptr,92); ptr1=ptr1+1; *ptr1='\0'; datei=fopen(strcat(ptr,"sudoku_geloest.txt"),"w+"); if(datei==NULL){ return -1; printf("Fehler beim Schreiben der Datei!"); } fprintf(datei,"Eingabefehler"); fclose(datei); } return 0; }Geändert von sheepking (20. 12. 2011 um 01:13 Uhr)
-
19. 12. 2011, 23:01 #2
Re: [C] Problem bei Stringübergabe an Funktion
Ich glaube eher dein Fehler passiert schon beim Anlegen.Der Fehler liegt bei der Übergabe des Pfades an die Funktion
faeld=(char**)malloc(9*sizeof(char*));
-
20. 12. 2011, 00:02 #3
Re: [C] Problem bei Stringübergabe an Funktion
Habs mal geändert, das scheint aber keinen Unterschied zu machen


Das ist was mir der Debugger beim Pfad sagt...
Edith 2:
Okay, jetzt scheint es irgendwie zu funktionieren, das Programm lässt sich starten per Doppelklick, dann führt es alles aus wie es soll
Wenn ich das Programm aber per Kommandozeile starte (über die Visual Studio kommandzeile stürzt es sofort ab, sonst) führt es aus bis es nach dem Pfad fragt, wenn dieser eingegeben ist stürzt das Programm ab...
Das trifft aber auch nur zu wenn ich es mit dem Visual Studio compiler kompiliere, wenn ich es mit dem GCC compiler von DEVC++ mache, funktioniert es einwandfrei...
Hier nochmal das gesamte Programm
Spoiler:
Code:/* Aufgaben: Geschickte Datenstrukturen [x] Wenige Call by Value [x] Wenige globals [x] Eingabe per form. Textdatei[x] Kommandozeilenparameter [x] Dateifehler abfangen [x] Linux - GCC [x] Prototypen + Beschreibung [x] Namensgebung [x] Eingabefehlerausgabe [x] */ /* Bedienungsanleitung: Der Sudokulöser lässt sich starten per Doppelklick, indem man ihn in die Kommandozeile zieht, oder indem man das zu lösende Sudoku direkt auf die .exe per drag&drop schiebt. Wird es per Kommandozeile aufgerufen gibt es 2 Möglichkeiten: Man kann bevor das Programm ausgeführt wird den Pfad zum zu lösenden Sudoku mit Leerzeichen getrennt angeben: "37843-sudoku.exe pfad\zum\sudoku.file" oder das Programm direkt aufrufen und nachträglich den Pfad zum Sudoku angeben: "37843-sudoku.exe Bitte geben Sie den Pfad zum zu loesenden Sudoku an: pfad\zum\sudoku.file" Alternativ, wenn das File im selben Ordner wie das Programm liegt, muss nicht der gesamte Pfad angegeben werden, sondern lediglich der Dateiname. Wird nun per Returntaste bestätigt, wird das Lösungsprogramm in Gang gesetzt. Der Löser wird alle gefundenen Lösungen in der Kommandozeile ausgeben, die erste gefundene Lösung wird zudem in ein Textfile namens "sudoku-geloest.txt" geschrieben. Liegt ein Eingabefehler vor, schreibt das Programm "Eingabefehler" in die sudoku-geloest.txt". */ /*Includes*/ #include <stdio.h> #include <string.h> #include <stdlib.h> /*Constants*/ /*Globals*/ //static char feld[9][9]; /*Prototypes*/ int readSudoku(char *path, char** faeld); //Liest das Sudoku aus einer Datei ein void printSudoku(char** faeld); //Gibt das Sudoku in der Kommandozeile aus int allePruefen(int x, int y, int wert, char** faeld); //Prüft die Integrität der Werte, ruft andere Prüfungsfunktionen auf int xAchsePruefen(int y, int wert, char** faeld); //Prüft die Waagrechte Integrität int yAchsePruefen(int x, int wert, char** faeld); //Prüft die Vertikale Integrität int boxPruefen(int x, int y, int wert,char** faeld); //Prüft die Integrität in der jeweiligen Box int loesen(int x, int y, char *pathptr, int *lsptr, char** faeld); //Rekursiver Lösungsalgorithmus int writeSudoku(char *ptr, char** faeld); //Gibt gelöstes Sudoku in Datei aus int writeError(char *ptr); //Gibt Fehlermeldung in Datei aus /*Main Routine*/ int main(int argc, char *argv[]){ char* pfad; char** faeld; int loesungen=0; char asdfblub; pfad=(char*)malloc(200*sizeof(char)); pfad[0]='\0'; faeld=(char**)malloc(9*sizeof(char*)); for(asdfblub=0;asdfblub<10;asdfblub++) faeld[asdfblub]=(char*)malloc(9*sizeof(char)); //Leert den String if(argc>1){ strcat(pfad,argv[1]); } else { printf("Bitte geben Sie den Pfad zum zu loesenden Sudoku an:\n"); scanf("%s",pfad); //printf("%s",pfad); } if(readSudoku(pfad, faeld) < 0) return 0; printf("Urspruengliches Sudoku:\n"); printSudoku(faeld); printf("\n"); loesen(0, 0, pfad, &loesungen, faeld); //Beginne mit der Lösung /*Loesung abgeschlossen*/ printf("Loesungen: %d\n", loesungen); if(loesungen==0) writeError(pfad); free(*faeld); free(pfad); return 0; } /*Functions*/ int loesen(int x, int y, char *pathptr, int *lsptr, char** faeld) { int i; if(x == 9) { // Zeilenende erreicht y++; x = 0; if(y == 9) // Ende des Sudokufeldes erreicht return 1; } if(faeld[y][x] > -16 && faeld[y][x] > 0) // Feld schon gesetzt return loesen(x+1, y, pathptr, lsptr, faeld); // Nächstes Feld for(i = 1; i <= 9; i++) { // Keine Zahl if(!allePruefen(x, y, i, faeld)) { // Integrität prüfen faeld[y][x] = i; // Falls Zahl passt einsetzen if(loesen(x+1, y, pathptr, lsptr, faeld)) { // Nächstes Feld *lsptr=*lsptr+1; // Lösung gefunden if(*lsptr < 2){ writeSudoku(pathptr, faeld); //Erste Lösung in Datei schreiben } printf("Loesung %d:\n", *lsptr); printSudoku(faeld); printf("\n"); } } } faeld[y][x] = -16; // Keine Zahl hat gepasst, Feld wird wieder auf ' ' gesetzt return 0; } int readSudoku(char *path, char** faeld) { FILE *datei; int a, b; char ovw[200]; char ipbuffer[12] = {0}; ovw[0]='\0'; strcat(ovw,path); if((datei = fopen(ovw, "r")) == NULL) { printf("Datei nicht gefunden!\n"); writeError(path); return -1; } for(a = 0; a < 9; a++) { if(fgets(ipbuffer, 12, datei) == NULL) { printf("Datei zu kurz!\n"); writeError(path); fclose(datei); return -1; } for(b = 0; b < 9; b++) { if(((ipbuffer[b] - '0') < 0 || (ipbuffer[b] - '0' > 9)) && !(ipbuffer[b] - '0' == -16)){ printf("Eingabefehler!\n"); writeError(path); fclose(datei); return -1; } else { faeld[a][b] = ipbuffer[b] - '0'; } } } fclose(datei); return 0; } void printSudoku(char** faeld) { int i, j; for(i = 0; i < 9; i++) { for(j = 0; j < 9; j++) { if(faeld[i][j]==-16) printf(" "); else printf("%d", faeld[i][j]); } printf("\n"); } } int allePruefen(int x, int y, int wert, char** faeld) { if((xAchsePruefen(y, wert, faeld)+yAchsePruefen(x, wert, faeld)+boxPruefen(x, y, wert, faeld))>0) return 1; return 0; } int xAchsePruefen(int y, int wert, char** faeld) { int i; for(i = 0; i < 9; i++) if(faeld[y][i] == wert) return 1; return 0; } int yAchsePruefen(int x, int wert, char** faeld) { int i; for(i = 0; i < 9; i++) if(faeld[i][x] == wert) return 1; return 0; } int boxPruefen(int x, int y, int wert, char** faeld) { int xb, yb, i, j; xb = (int)(x / 3) * 3; yb = (int)(y / 3) * 3; for(i = yb; i < yb + 3; i++) for(j = xb; j < xb + 3; j++) if(faeld[i][j] == wert) return 1; return 0; } int writeSudoku(char *ptr, char** faeld) { FILE* datei; int x, y; char *ptr1; if(strrchr(ptr,92)==NULL){ datei=fopen("sudoku_geloest.txt","w+"); if(datei==NULL){ return -1; printf("Fehler beim schreiben der Datei!"); } for(x=0; x<9; x++){ for(y=0; y<9; y++){ fprintf(datei, "%c",(faeld[x][y]+48)); } if(!(x==8)) fprintf(datei, "\n"); } fclose(datei); } else { ptr1 = strrchr(ptr,92); ptr1=ptr1+1; *ptr1='\0'; datei=fopen(strcat(ptr,"sudoku_geloest.txt"),"w+"); if(datei==NULL){ return -1; printf("Fehler beim schreiben der Datei!"); } for(x=0; x<9; x++){ for(y=0; y<9; y++){ fprintf(datei, "%c",(faeld[x][y]+48)); } if(!(x==8)) fprintf(datei, "\n"); } fclose(datei); } return 0; } int writeError(char *ptr){ FILE* datei; char *ptr1; if(strrchr(ptr,92)==NULL){ datei=fopen("sudoku_geloest.txt","w+"); if(datei==NULL){ return -1; printf("Fehler beim Schreiben der Datei!"); } fprintf(datei,"Eingabefehler"); fclose(datei); } else { ptr1 = strrchr(ptr,92); ptr1=ptr1+1; *ptr1='\0'; datei=fopen(strcat(ptr,"sudoku_geloest.txt"),"w+"); if(datei==NULL){ return -1; printf("Fehler beim Schreiben der Datei!"); } fprintf(datei,"Eingabefehler"); fclose(datei); } return 0; }
Edith 3:
Hier nochmal die Absturzmeldung:

Edith 4:
Im weiterführenden Debugging erzählt mir Windows dass ich einen Heap beschädige!
omg ich bin ein Depp ich habs -.-
Ich hab meine Schleife bei der zweiten Initialisierung bis zu 9 hochzählen lassen, wobei das ja der index ist, der eigentlich nur bis 8 hätte gehen dürfen...
Vielen Dank für die Hilfe und gute Nacht!
Thread kann geschlossen werden!Geändert von sheepking (20. 12. 2011 um 01:12 Uhr)
-


Zitieren

mehr lesen...







Resident Evil 6 erscheint in...
Heute, 15:21 in gulli:news