Problem mit fwrite und Datentypen
-
Hallo,
wir schreiben in unserer Uebung zur Vorlesung "Informatik fuer Maschinenbauer" zur Zeit einen Vokabeltrainer in C. Das Problem: der Code kompiliert, stuerzt aber beim Ausfuehren der Funktion vokabeleingabe in der Zeile
fwrite(&vokabeln,sizeof(vokabelsatz),1,datenstrom);
mit einem Segmentation fault ab (gcc-Ausgabe: "program exited with code: 139").
Wenn ich die Warnings, die gcc beim Kompilieren ausspuckt (uebung11-vokabeltrainer-v3.c:81:3: warning: format ‘%s’ expects type ‘char ’, but argument 2 has type ‘char ()[30]’), richtig verstanden habe, koennte es an einem Problem mit den Datentypen liegen, aber ich habe keine Idee, wie mit diesem Problem umzugehen ist.
Auch unser Uebungsleiter hat den Fehler leider nicht finden koennen.
Hier nun der Code:
#include <stdio.h> #include <string.h> // Uebung 05.07.10 // 1. Vokabeln einlesen // 2. Vokabeln vergleichen // Funktionen // Datensaetze editieren // Vokabeln abfragen void vokabelabfrage(); void vokabeleingabe(); // int trained = 1; typedef struct Wort{ // Wort = Variable char lang_one[30]; // Englisch char lang_two[30]; // Deutsch // int trained; }vokabelsatz; // vokabelsatz = neuer Datentyp // Array mit 2 Feldern des neuen Datentyps vokabelsatz vokabeln[20]; int main() { int loop=1; char auswahl='0'; // Programmschleife, die erst auf Wunsch des Benutzers endet while(loop){ // Auswahlmenu printf("Bitte geben Sie eine 1 ein, wenn Sie Vokabeln ueben moechten, eine 2 wenn Sie Vokabeln eingeben moechten und 3 zum beenden: \n"); scanf("%c",&auswahl); switch(auswahl) { case('1'): printf("Herzlich willkommen bei der Vokabelabfrage!\n"); vokabelabfrage(); break; case('2'): printf("Geben Sie Vokabeln ein: \n"); vokabeleingabe(); break; case('3'): printf("Das Programm wird nun beendet!\n"); loop=0; break; default: printf("Fehler: Diese Eingabe ist nicht moeglich! \n"); break; } } } int i; int n; void vokabelabfrage(){ for(i=1; i<3; i++){ printf("Uebersetzen Sie bitte den Begriff: \n"); printf("%s",&vokabeln[i].lang_two); printf("\n"); scanf("%s",&vokabeln[i].lang_one); if(memcmp(vokabeln[i].lang_one,vokabeln[i].lang_two,n)==0){ printf("Richtig! \n"); //vokabeln[i].trained = 0; } else{ printf("Falsch! \n"); } /*for(vokabeln[i].trained = 0;){ printf("Diese Vokabeln sollten Sie nochmal ueben: " ); printf("%s", vokabeln[i].trained = 0); }*/ } } int i; void vokabeleingabe(){ // Datenstrom angeben: FILE *datenstrom; // und einen Datensatz vokabelsatz vokabeln; int loop=1; char c; // checken ob Datei lesbar if(datenstrom = fopen("vokabeldatei.txt","ab+")!=NULL) { // schleife um mehrere vokabelsaetze eingeben zu koennen while(loop) { // input aufraeumen: do{c=getchar();}while(c!='\n'); // abfragen des vokabelsatzes printf("Bitte geben Sie das Wort in Englisch ein: \n"); scanf("%s",&vokabeln.lang_one); // printf("%p\n", &vokabeln.lang_one); printf("Bitte geben Sie das Wort in Deutsch ein: \n"); scanf("%s",&vokabeln.lang_two); // vokabeln.trained=0; // schreiben der Daten auf Platte: fwrite(&vokabeln,sizeof(vokabelsatz),1,datenstrom); //sicherstellen dass alles geschrieben wurde: fflush(datenstrom); do{c=getchar();}while(c!='\n'); // Abfrage ob noch mehr Datensaetze eingegeben werden sollen printf("Weitere Datensaetze eingeben? n=Nein, alles andere: fortfahren "); scanf("%c",&c); if(c=='n') loop=0; } // schliessen der Datei fclose(datenstrom); } else{ printf("Sie koennen die Datei leider nicht oeffnen!"); } }
-
int i;
int n;
void vokabelabfrage(){globale Variablen, pfui!
if(memcmp(vokabeln[i].lang_one,vokabeln[i].lang_two,n)==0){
n ist undefiniert!
int i;
void vokabeleingabe(){globale Variable, pfui!
Du solltest dich entscheiden, ob du nun auf das Array indiziert zugreifst, oder nicht!
vokabeln[i].lang_onevokabeln.lang_one
for(i=1; i<3; i++){
Arrays beginnen mit 0-Index!
Prinzipiell arbeiten deine beiden Funktionen IMHO falsch.
Die Eingabefunktion sollte neue Vokabeln(falls noch nicht vorhanden) in die Datei schreiben und diese dann schließen.
Die Auswertung sollte diese Datei dann satzweise lesen, auf Gleichheit prüfen und dann die Datei wieder schließen.
Ein Vokabelnarray brauchst du somit gar nicht und hast somit auch keine Probleme bei der Dimensionierung des Arrays.
-
[quote="Wutz"]
...
Die Eingabefunktion sollte neue Vokabeln(falls noch nicht vorhanden) in die Datei schreiben und diese dann schließen.
Die Auswertung sollte diese Datei dann satzweise lesen, auf Gleichheit prüfen und dann die Datei wieder schließen.
...pfui!
-
So z.B. kann es funktionieren.
Ich nehme die Aufwangsentschädigung eures Übungsleiters gern entgegentypedef struct { // Wort = Variable char lang_one[30]; // Englisch char lang_two[30]; // Deutsch // int trained; }vokabelsatz; // vokabelsatz = neuer Datentyp const char *deutschFuerEnglisch(const char *dateiname,char *englisch) { vokabelsatz paar; FILE *datei=fopen(dateiname,"rb"); if(!datei) return 0; while( 1==fread(&paar,sizeof paar,1,datei) ) if( !strcmp(paar.lang_one,englisch) ) return fclose(datei),strcpy(englisch,paar.lang_two); fclose(datei); return 0; } int addiereVokabelPaar(const char *dateiname,vokabelsatz paar) { FILE *datei; if( deutschFuerEnglisch(dateiname,paar.lang_one) ) return 0; if( !(datei=fopen(dateiname,"a+b")) ) return perror(dateiname),0; return 1==fwrite(&paar,sizeof paar,1,datei) & !fclose(datei); } main() { char *d="vokabeln.bin"; vokabelsatz p; char c; while(1) switch((c=getchar())=='\n'?getchar():c) { case '1': puts("neu e/d:");scanf("%s",p.lang_one);scanf("%s",p.lang_two);addiereVokabelPaar(d,p);break; case '2': puts("suche e:");scanf("%s",p.lang_one);if(deutschFuerEnglisch(d,p.lang_one)) puts(p.lang_one);break; default: return 0; } return 1; }
Als weitere Übungen kannst du mal probieren:
- Ignorierung Groß-Kleinschreibung
- Übersetzung andersrum
- Mehrfach-Übersetzungsalternativen
- sortierte Komplettliste ausgeben
- ...