3 Stimmen

Fread/fwrite string in C

Ich habe eine Binärdatei, die Datensätze enthält. Die Struktur der Datei ist wie folgt:

Struktur (siehe unten) Name String Adresse String

Die fragliche Struktur:

typedef struct{
    char * name;
    char * address;
    short addressLength, nameLength;
    int phoneNumber;
}employeeRecord;
employeeRecord record;

Ich erhalte den Namen folgendermaßen:

char name[50];
printf("\nName:");
fgets(name,50,stdin);
record.nameLength = strlen(name)-1;
record.name = malloc(sizeof(char)*record.nameLength);
strcpy(record.name,name);

Ich schreibe die Struktur, dann den Namen und dann die Adresse (wie oben erwähnt).

fwrite(&record.name,sizeof(char),record.nameLength,fp);

wo fp ein Dateizeiger ist.

Jetzt schließe ich die Datei. Wenn ich jedoch später die Daten aus der Datei lesen möchte, glaube ich, dass ich die Struktur einlesen, die nameLength-Variable lesen, genügend Speicher für den Namen allozieren und dann den Namen in die Variable einlesen muss.

So:

char *nameString = malloc(sizeof(char)*record.nameLength);
fread(nameString,sizeof(char),record.nameLength,fp);
printf("\nName: %s",nameString);

Aber wenn ich das versuche, erhalte ich keine gültigen Daten. Beispiel:

Eingegebener Name ist: Joseph (6 Zeichen)
Ausgabedaten:
Name-Länge ist 6 (korrekt),
Name ist A         (also Müll)

Offensichtlich mache ich etwas falsch. Könnte mir jemand helfen?

2voto

John Knoeller Punkte 32285

Ich sehe zwei Probleme mit dem Code, du setzt record.nameLength zu klein und du übergibst den falschen Zeiger an fwrite für den Namen. record.name ist bereits ein Zeiger.

Ändere dies

record.nameLength = strlen(name)-1;
...
fwrite(&record.name,sizeof(char),record.nameLength,fp);

zu diesem

record.nameLength = strlen(name);
...
fwrite(record.name,sizeof(char),record.nameLength,fp);

Du hast auch ein Problem beim Lesen, da du das Terminierungszeichen \0 nicht in deine Datei schreibst. Wenn du zurück liest, musst du diesen Terminator explizit hinzufügen.

char *nameString = malloc(sizeof(char)* (record.nameLength + 1));
fread(nameString,sizeof(char),record.nameLength,fp);
nameString[record.NameLength] = '\0';

1voto

zneak Punkte 129366

Das Problem liegt darin, dass Sie den Zeiger auf den char* in Ihrem fwrite übergeben:

fwrite(&record.name,sizeof(char),record.nameLength,fp);

Dies bedeutet, dass Sie anstelle des Namens die Speicheradresse des Namens schreiben. Fwrite erwartet einen Zeiger auf die Daten, die geschrieben werden sollen - in Ihrem Fall ist das der Zeiger auf die char-Daten, nicht der Zeiger auf den Zeiger der char-Daten.

Übergeben Sie stattdessen record.name anstelle von &record.name und es sollte funktionieren:

fwrite(record.name, sizeof(char), record.nameLength, fp);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X