Frage

Ich mag Strings speichern in einer Binärdatei, zusammen mit vielen anderen Daten im den Code unter Verwendung von (wenn ich es wirklich verwenden können die Saiten malloc'd) Ich kann in die Datei schreiben. Ive sah in einem Hex-Editor auf sie. Ich bin nicht sicher im den Nullabschluss Schreiben korrekt (oder wenn ich muss). wenn ich lese wieder heraus bekomme ich die gleiche String-Länge, die ich gespeichert, aber nicht die Zeichenfolge. was mache ich falsch?

FILE *fp = fopen("mybinfile.ttt", "wb");

char drumCString[6] = "Hello\0";
printf("%s\n", drumCString);    
//the string length + 1 for the null terminator
unsigned short sizeOfString = strlen(drumCString) + 1;
fwrite(&sizeOfString, sizeof(unsigned short), 1, fp);

//write the string
fwrite(drumCString, sizeof(char), sizeOfString, fp);

fclose(fp);

fp = fopen("mybinfile.ttt", "rb");  

unsigned short stringLength = 0;
fread(&stringLength, sizeof(unsigned short), 1, fp);

char *drumReadString = malloc(sizeof(char) * stringLength);
int count = fread(&drumReadString, sizeof(char), stringLength, fp);

//CRASH POINT
printf("%s\n", drumReadString);

fclose(fp); 
War es hilfreich?

Lösung

Sie falsch machen beim Lesen. Sie haben die & für die Zeigervariable setzen, die ist, warum es Segmentierungsfehler gibt.

ich entfernt, dass es funktioniert gut und es gibt Hallo richtig.

int count = fread(drumReadString, sizeof(char), stringLength, fp);

Andere Tipps

Ich sehe ein paar Probleme, einige problematisch, einige stilistische.

  • Sie sollten wirklich testen Sie die Rückgabewerte von malloc, fread und fwrite, da es möglich ist, dass die Zuweisung fehlschlagen kann, und keine Daten können gelesen oder geschrieben werden.
  • sizeof(char) ist immer 1 ist, gibt es keine Notwendigkeit, indem sie es zu vermehren.
  • Das Zeichenfeld "Hello\0" ist eigentlich 7 Bytes lang. Sie brauchen nicht einen überflüssigen Nullabschluss hinzuzufügen.
  • Ich ziehe das Idiom char x[] = "xxx"; eher als eine bestimmte Länge spezifiziert (es sei denn Sie ein Array wollen länger als die Zeichenfolge natürlich).
  • Wenn Sie fread(&drumReadString ..., Sie überschreiben tatsächlich die Zeiger , nicht die Erinnerung es verweist. Dies ist die Ursache für den Absturz. Es sollte fread(drumReadString ... werden.

Ein paar Tipps:

1

Ein Abschluss \0 ist in jedem doppelten Anführungszeichen Zeichenfolge implizit, und durch eine zusätzliche am Ende hinzufügen, die Sie mit zwei enden. Die beiden folgenden Initialisierungen sind identisch:

char str1[6] = "Hello\0";
char str2[6] = { 'H', 'e', 'l', 'l', 'o', '\0', '\0'};

So

char drumReadString[] = "Hello";

genug ist, und die Größe des Arrays ist optional, wenn es wie folgt initialisiert wird, wird der Compiler die erforderliche Größe herauszufinden (6 Bytes).

2

Wenn Sie eine Zeichenfolge zu schreiben, könnte man genauso gut schreiben Sie einfach alle Zeichen in einem Rutsch (statt sizeOfString mal eins nach dem anderen Zeichen schreiben):

fwrite(drumCString, sizeOfString, 1, fp);

3

Auch wenn nicht so häufig für ein normales Desktop-PC-Szenario kann malloc NULL zurück, und Sie werden wegen der immer überprüft das Ergebnis von der Entwicklung einen habbit profitieren in Embedded-Umgebungen, NULL nicht immer ein unwahrscheinliches Ergebnis ist.

char *drumReadString = malloc(sizeof(char) * stringLength);
if (drumReadString == NULL) {
        fprintf(stderr, "drumReadString allocation failed\n");
        return;
}

Sie das abschließende NUL nicht schreiben, brauchen Sie nicht zu, aber dann über Sie müssen denken, dass es das Hinzufügen beim Lesen. dh malloc StringLength + 1 Zeichen, lesen StringLength Zeichen und eine \0 am Ende hinzufügen, was gelesen wurde.

Nun ist die übliche Warnung: Wenn Sie binäre Datei, die die Art und Weise schreiben Sie denn hier sind, haben Sie viele unausgesprochene Annahmen, die Ihr Format schwierig zu portieren, manchmal sogar auf eine andere Version des gleichen Compiler - Ich habe gesehen, Standardausrichtung in struct Änderungen zwischen Compiler-Versionen.

Einige mehr hinzuzufügen zu paxdiablo und AProgrammer - wenn Sie malloc verwenden, in die Zukunft gehen, tun Sie es einfach aus der sich gehen. Es ist besser, Form und bedeutet, dass Sie nicht zu debuggen, wenn wechseln.

Außerdem bin ich nicht vollständig die Verwendung des unsigned short zu sehen, wenn Sie sich auf dem Schreiben eine binäre Datei planen, berücksichtigen, dass der unsigned char-Typ im Allgemeinen von Größe Byte ist, ist es sehr bequem für diesen Zweck zu machen.

Sie entfernen Sie Ihre & drumReadString im fread function.You einfach verwenden drumReadString in dieser Funktion als ganesh mentioned.Because ist drumReadString ein array.Array auf Zeiger, die auf die Speicherstelle direkt ähnlich ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top