C: L'écriture et la lecture d'une chaîne vers et à partir d'un fichier binaire

StackOverflow https://stackoverflow.com/questions/2415495

  •  19-09-2019
  •  | 
  •  

Question

Je veux stocker des chaînes dans un fichier binaire, ainsi que beaucoup d'autres données, im en utilisant le code ci-dessous (quand je l'utilise pour de vrai les chaînes seront malloc'd) Je peux écrire dans le fichier. Ive a regardé dans un éditeur hexadécimal. Je ne suis pas sûr im écrire correctement le terminateur nul (ou si je dois). quand je lis en arrière sur i obtiens la même longueur de la chaîne que j'emmagasinés, mais pas la chaîne. ce que je fais mal?

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); 
Était-ce utile?

La solution

Vous faites mal en lisant. vous avez mis le & pour la variable de pointeur qui est pourquoi il donne une erreur de segmentation.

Je retirai que cela fonctionne très bien et il retourne Bonjour correctement.

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

Autres conseils

Je vois quelques problèmes, certains problèmes, certains style.

  • Vous devriez vraiment tester les valeurs de retour de malloc, fread et fwrite car il est possible que l'allocation peut échouer, et aucune donnée ne peut être lu ou écrit.
  • sizeof(char) est toujours 1, il n'y a pas besoin de multiplier par elle.
  • Le tableau caractère "Hello\0" est en fait 7 octets. Vous n'avez pas besoin d'ajouter une terminaison null superflue.
  • Je préfère le char x[] = "xxx"; idiome plutôt que de spécifier une longueur définie (sauf si vous voulez un tableau plus que la chaîne bien sûr).
  • Lorsque vous fread(&drumReadString ..., vous écrasez les symboles pointeur , pas la mémoire il pointe. Ceci est la cause de votre accident. Il devrait être fread(drumReadString ....

Quelques conseils:

1

Une terminaison \0 est implicite dans toute double chaîne de devis, et en ajoutant un montant supplémentaire à la fin vous vous retrouvez avec deux. Les deux initialisations suivantes sont identiques:

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

char drumReadString[] = "Hello";

est suffisant, et en spécifiant la taille du tableau est en option lors de son initialisation comme celui-ci, le compilateur comprendre la taille requise (6 octets).

2

Lors de l'écriture d'une chaîne, vous pourriez tout aussi bien il suffit d'écrire tous les caractères en une seule fois (au lieu d'écrire un par un caractère fois sizeOfString):

fwrite(drumCString, sizeOfString, 1, fp);

3

Bien que pas si commun pour un scénario de PC de bureau normal, malloc peut retourner NULL et vous bénéficierez de développer un Habitude de toujours vérifier le résultat parce que dans les environnements embarqués, obtenir NULL est pas un résultat improbable.

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

Vous n'écrivez pas la terminaison NUL, vous n'avez pas besoin, mais alors vous devez penser à ajouter lors de la lecture. à savoir malloc StringLength + 1 char, lire les caractères StringLength et ajouter un \0 à la fin de ce qui a été lu.

Maintenant, l'avertissement habituel: si vous écrivez fichier binaire la façon dont vous faites ici, vous avez beaucoup d'hypothèses inexprimées qui rendent votre format difficile au port, parfois même à une autre version du même compilateur - Je l'ai vu alignement par défaut des modifications struct entre les versions du compilateur.

Un peu plus à ajouter à paxdiablo et AProgrammer - si vous allez utiliser malloc dans l'avenir, il suffit de faire dès le départ. Il vaut mieux la forme et signifie que vous ne devrez pas debug lors de la commutation.

De plus je ne vois pas pleinement l'utilisation du court non signé, si vous envisagez d'écrire un fichier binaire, considère que le type unsigned char est généralement de l'octet de taille, ce qui rend très pratique à cette fin.

Vous suffit de retirer votre & drumReadString dans le function.You fread utiliser simplement drumReadString dans cette fonction comme ganesh mentioned.Because, drumReadString est un array.Array est similaire à des pointeurs qui pointent vers l'emplacement de mémoire directement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top