2016-04-04 7 views
2

J'essaie actuellement de lire 256 octets à partir d'un fichier binaire et de ne recevoir aucune sortie (ou erreur) lors de l'exécution de mon programme. Je suis un peu confus lorsque je me trompe. Tenter de lire chaque octet comme un char et un magasin comme un tableau de longueur 256. J'ai déjà passé en revue des questions similaires sur SO et n'ont pas eu de chance jusqu'à présent. Version simplifiée de mon code ci-dessous:C: Lecture des octets à partir du fichier binaire

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]){ 
    FILE *binary = fopen(argv[1], "rb"); 
    char bytesFromBinary[256]; 

    fread(&bytesFromBinary, 1, 256, binary); 
    printf("%s", bytesFromBinary); 
    return 0; 
} 
+9

Vous essayez de lire * binaire *, puis de l'imprimer en utilisant un spécificateur de format * chaîne *. Quelle sortie attendez-vous si les données binaires commencent par un octet nul ou si les octets sont toutes des valeurs non imprimables?Ou que se passe-t-il si ces octets * ne contiennent pas de terminateur nul pour dire 'printf' où il s'arrête? –

+1

L'itération de votre tableau et l'impression de chaque valeur du tableau en tant que nombre devraient vous aider à voir ce qui se trouve dans le tableau car il n'interprétera pas les caractères ASCII étendus ou restreints, mais les valeurs entières. – callyalater

+0

Quel est le contenu actuel du fichier? Pouvez-vous poster un extrait? –

Répondre

2

Une utilisation de base de fread vérifiera le retour par rapport au nombre d'octets attendus pour valider que vous lisez ce que vous avez l'intention de lire. La sauvegarde du retour vous permet également de gérer les lectures partielles.

L'exemple suivant lit un minimum de 16 octets à la fois du fichier donné comme premier argument (ou stdin par défaut si aucun fichier est donné) dans buf et sorties chaque valeur à stdout en hexadécimal format.

#include <stdio.h> 

#define BUFSZ 16 

int main (int argc, char **argv) { 

    unsigned char buf[BUFSZ] = {0}; 
    size_t bytes = 0, i, readsz = sizeof buf; 
    FILE *fp = argc > 1 ? fopen (argv[1], "rb") : stdin; 

    if (!fp) { 
     fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); 
     return 1; 
    } 

    /* read/output BUFSZ bytes at a time */ 
    while ((bytes = fread (buf, sizeof *buf, readsz, fp)) == readsz) { 
     for (i = 0; i < readsz; i++) 
      printf (" 0x%02x", buf[i]); 
     putchar ('\n'); 
    } 
    for (i = 0; i < bytes; i++) /* output final partial buf */ 
     printf (" 0x%02x", buf[i]); 
    putchar ('\n'); 

    if (fp != stdin) 
     fclose (fp); 

    return 0; 
} 

(Remarque: bytes == readsz uniquement lorsque le paramètre size à fread est 1 Le rendement est le nombre de items lecture et chaque article est seulement égale à 1 pour char valeurs de type.)

Exemple d'utilisation/Sortie

$ echo "A quick brown fox jumps over the lazy dog" | ./bin/fread_write_hex 
0x41 0x20 0x71 0x75 0x69 0x63 0x6b 0x20 0x62 0x72 0x6f 0x77 0x6e 0x20 0x66 0x6f 
0x78 0x20 0x6a 0x75 0x6d 0x70 0x73 0x20 0x6f 0x76 0x65 0x72 0x20 0x74 0x68 0x65 
0x20 0x6c 0x61 0x7a 0x79 0x20 0x64 0x6f 0x67 0x0a 

Examinez l'exemple et faites-moi savoir si y Vous avez des questions

0

Vous n'avez pas déclaré une variable assez longue. La déclaration char bytesFromBinary[256]; réserve 256 octets et fread remplit tous les 256 octets. Il n'y a pas de fin '\0' et il n'y a pas d'espace pour cela, donc tout ce qui arrive en mémoire est écrasé/détruit. Cela entraînera déjà toutes sortes d'erreurs aléatoires et des accidents. Ensuite, dans printf, vous essayez de l'imprimer, et la fonction continuera à fonctionner dans la mémoire jusqu'à ce qu'elle rencontre un '\0' pour l'arrêter, donc si le programme le fait, vous obtiendrez une impression de mémoire, peut-être court, peut-être des milliers de caractères (non imprimables) longtemps.

Vous devez déclarer la variable toujours plus longue, pour avoir de l'espace pour le suivi '\0': char bytesFromBinary[257];. Mieux vaut utiliser sizeof(var)-1 dans fread, ou utiliser une constante pour la longueur désirée et le déclarer avec +1.

+0

changé en 'bytesFromBinary [257]' et la même sortie (aucun) – GregH

-1

Echec de l'impression d'un bloc d'octets en tant que chaîne de style C.

Il existe deux types de fichiers: un fichier binaire et un fichier texte. Pour lire/écrire un fichier, vous devez l'ouvrir dans le mode correspondant.

Si votre fichier est créé de cette façon:

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) 
{ 
    FILE *binary = fopen("file.txt", "wbx"); 
    if(!binary) 
    { 
     perror("fopen()"); 
     exit(EXIT_FAILURE); 
    } 
    char bytesToBinary[256] = ":-)"; 

    fwrite(bytesToBinary, 1, 256, binary); 
    fclose(binary); 
    return 0; 
} 

Votre code doit réussir.

+0

Je m'ouvre en mode binaire car c'est un fichier binaire. Vous ne savez pas ce que vous voulez corriger ici – GregH

+0

binary signifie 'caractères non-imprimables'. Si vous essayez de les imprimer de toute façon, vous aurez un comportement étrange. – Aganju

+0

Le problème ici est * not * que ce n'est pas ouvert en mode binaire. – immibis