2010-05-04 1 views
5

ich eine stucture haben in Datei:Schreibzeiger in C

typedef struct student { 
    char *name; 
    char *surname; 
    int age; 
} Student; 

Ich muss es Binär-Datei zu schreiben.

Student *s = malloc(sizeof(*s)); 

ich meine Struktur mit Daten füllen und dann schreibe ich in die Datei:

fwrite(s, sizeof(*s), 1, fp); 

In meiner Datei muß nicht einen Namen und Nachnamen bestehen, ist es ein Adressen von char *. Wie kann ich schreiben, um ein Wort, keine Adressen abzulegen?

Antwort

0

Sie müssen dereferenzieren s und einzeln auszuschreiben jedes Element der Struktur tatsächlich thecontents in die Datei schreiben:

size_t nameCount = strlen(s->name) + 1; 
fwrite(s->name, sizeof(char), nameCount, fp); 

size_t surnameCount = strlen(s->surname) + 1; 
fwrite(s->surname, sizeof(char), surnameCount, fp); 
+1

Das wird nicht funktionieren mit der gesetzten Strukturdefinition aussehen wollen - 'sizeof (s-> Name)' die geben Größe eines 'char *'. – caf

+0

Yup, du hast recht - ich habe die Größe geändert, um zu strlen –

+0

so jetzt müssen Sie es zu strlen() ändern * sizeof (char) ... (Nun, sizeof (char) wird 1 sein, nur für die Prinzip: – rkellerm

10

Sie dereferenzieren den Zeiger benötigen und die Teile der Struktur schreiben. (Sie sollten nicht eine Struktur direkt, fwrite sondern seine Teile kodieren und schreiben jene:

Student *s = malloc(sizeof(*s)); 
s->name = "Jon"; 
s->surname = "Skeet"; 
s->age = 34; 

// .... 

fwrite(s->name, sizeof(char), strlen(s->name) + 1, fp); 
fwrite(s->surname, sizeof(char), strlen(s->surname) + 1, fp); 

//This one is a bit dangerous, but you get the idea. 
fwrite(&(s->age), sizeof(s->age), 1, fp); 
+0

aber ich habe etwa 10 Felder in der Struktur.Sein sehr langen Code –

+1

Dann schreiben Sie eine Funktion, die alles davon schreibt, und rufen Sie einfach das, so: 'int fwriteStudent (Student * s, FILE * fp); ', und denken Sie daran, diese Funktion bei der Änderung Ihrer Strukturdefinition zu aktualisieren –

+0

@Sergey: Sie können diese Operationen in eine einzige Funktion kapseln, also muss es nicht * * * * sehr lang sein. * –

3

, wenn Sie die Struktur direkt zu schreiben, wie es in einer Datei ist wollen Sie die Größen von Vor- und Nachnamen definieren anstatt sie dynamisch zuordnet.

typedef structure student { char name[100]; char surname[100]; int age; } 

sonst müssen Sie durch eine jede Info in der Struktur schreiben.

+0

-1: Fixed string max längen sind, wie h wie bemerkt, schlecht. –

+3

@Williham Totland - Ich habe einen Grund angegeben, warum Sie das tun würden. wenn Sie die Struktur so schreiben möchten, wie sie ist. nicht nur blind das als schlecht anmerken. Haben Sie eine bessere Idee, wenn Sie die Struktur in eine fwrite-Operation schreiben wollen? – SysAdmin

+0

Das Schreiben der Struktur als eine fwrite-Operation ist, wie schon erwähnt, eine Bad Idea ™. Es ist fast, aber nicht ganz vollständig nicht portabel und führt nicht immer zu den gewünschten Ergebnissen. Überlaufbare Zeichenfolgen sind eine Sicherheitsverletzung, die darauf wartet, ausgeführt zu werden. –

4

Sie werden die Daten, auf die durch die Struktur einige zusätzliche Arbeit zu schreiben, zu tun haben, Elemente - wahrscheinlich schreibe es einfach Element für Element.

Alternativ Ihre Struktur zu so etwas wie dies ändern:

typedef struct 
{ 
    char name[MAX_NAME_LEN]; 
    char surname[MAX_SURNAME_LEN]; 
    int age; 
} Student; 
+0

-1: Fixed String maximale Längen sind schlecht. Sehr schlecht. (Mmmmmkay?) –

+2

@Williham: feste String-Längen sind in bestimmten Fällen in Ordnung - für ein Hausaufgaben-Problem mit einem kleinen Datensatz ist es völlig angemessen, sie zu verwenden. Bei einer gepackten, aber komplexeren Darstellung handelt es sich um eine "vorzeitige Optimierung", dh um Ihre Worte zu benutzen, * "sehr schlecht" *. –

+0

Das [Hausaufgaben] -Tag erschien gut nachdem ich meine Antwort gegeben und meinen Kommentar abgegeben hatte. Auf jeden Fall entschuldigen [Hausaufgaben] nicht schlampigen Code. –

0

Beachten Sie, dass irgendwie, das Sie nicht in der Lage sein, die Felder in einer ‚normalen‘ Form, um zu sehen, weil Sie es in eine binäre Datei schreiben. Versuchen Sie, die Datei ohne das "b" im Modusargument von fopen (r + \ w \ a usw. anstelle von rb + \ wb \ ab) zu öffnen.

Sie können sehen, dass, wenn fread (aus der Binär-Datei, nachdem sie in „rb“ Modus zu öffnen, sollten Sie die Strukturfelder erhalten, wie erwartet.

0

Hier finden Sie die Felder einzeln ausschreiben müssen, wie andere gesagt haben. eine Sache, die das Lesen von Daten zurück zu schreiben, die String-Längen vor jedem Eintrag helfen kann, z. B.

size_t len; 
len = strlen(s->name)+1; 
fwrite(&len,sizeof(len),1,stream); 
fwrite(s->name,sizeof(*(s->name)),len,stream); 
... 

zurück zu lesen, ist dann eine Frage der

Student * s = malloc(sizeof(*s)); 
size_t len; 
fread(&len,sizeof(len),1,stream); 
s->name = malloc(len); 
fread(s->name,sizeof(*(s->name)),len,stream); 
... 
3

In C müssen Sie die Strukturen manuell serialisieren (in eine Reihe von Bytes konvertieren). Wenn Sie möchten, dass die von Ihnen ausgegebenen Daten von einer anderen Maschine gelesen werden können, müssen Sie das Endianness-Konto endianness verwenden.

Hier ist ein einfaches Beispiel der Struktur der Serialisierung (in eine Datei zu schreiben), abgesehen von Endian/abweichender Wortgröße und macht den Code portabel:

size_t length; 

length = strlen(s->name) + 1; 
fwrite(&length, sizeof(length), 1, fp); 
fwrite(s->name, 1, length, fp); 

length = strlen(s->surname) + 1; 
fwrite(&length, sizeof(length), 1, fp); 
fwrite(s->surname, 1, length, fp); 

fwrite(&s->age, sizeof(s->age), 1, fp); 

Und unserialize:

size_t length; 

fread(&length, sizeof(length), 1, fp); 
s->name = malloc(length); 
fread(s->name, 1, length, fp); 

fread(&length, sizeof(length), 1, fp); 
s->surname = malloc(length); 
fread(s->surname, 1, length, fp); 

fread(&s->age, sizeof(s->age), 1, fp); 

In einer realen Anwendung sollten Sie die Gültigkeit Ihrer Eingabe überprüfen und nicht blind davon ausgehen, dass die Eingabe gültig und vertrauenswürdig ist. Außerdem müssen Sie entscheiden, welche Byte-Reihenfolge Sie verwenden werden, um Ihre int s, size_t s usw. zu speichern, und stellen Sie sicher, dass Sie sie in der korrekten Byte-Reihenfolge lesen/schreiben, indem Sie bit shifting verwenden.

By the way, können Sie bei tpl, eine einfache binäre Serialisierung Bibliothek für C.