2017-03-02 2 views
1

J'étudie le fichier binaire en C++ de nos jours. J'ai une question sur la lecture et l'écriture de structure ou de classe dans un fichier binaire. Par exemple, si j'ai une structure comme,Enregistrement de la structure dans un fichier binaire et lecture seule de la valeur en C++

struct A { 
    char a1; 
    int a2; 
    double a3; 
}; 

Et puis je peux sauver une structure avec le code comme,

A a = {'a', 2, 3.5}; 
ofstream file; 
file.open("file.dat", ios::binary); 
file.write((char*)&a, sizeof(a)); 
file.close(); 

La question est, puis-je pas lu toute la structure, mais seulement la valeur dans la structure? Par exemple, si je veux lire la valeur entière de la structure, alors,

ifstream file; 
int i = 1; 
file.open("file.dat", ios::binary); 
file.seekg(sizeof(char), ios::beg); 
file.read((char*)&i, sizeof(i)); 
file.close(); 

Est-ce possible? Si ce n'est pas le cas, y a-t-il un moyen de lire seulement une valeur de la structure?

+0

la structure n'est pas alignée, vous devez donc aligner, –

+0

Il y a rembourrage entre les membres de la structure. 'a2' est à un décalage 4 du début de la structure, pas décalé 1 comme vous le supposez. Faites-le 'file.seekg (offsetof (A, a2), ios :: beg);'. Bien qu'il soit probablement plus facile de simplement lire toute la structure, après tout. –

+0

Les fichiers binaires dépendent généralement de la plateforme. Recherche "Endianess". De même, les pointeurs ne sont pas portables, en particulier entre les invocations du même exécutable. –

Répondre

0

Découvrez mon matériel de portabilité binaire pour avoir une idée générale des fichiers binaires et de leurs problèmes.

C'est une mauvaise idée d'écrire une structure entière sur un disque, même si vous avez l'intention de la relire dans le même programme. Mais si vous le faites, vous créez une image binaire sur le disque. Vous pouvez documenter cela. Il se composera de char bytes, de grands ou petits entiers endian de différentes tailles, de pointeurs (totalement inutiles pour vous), et de doubles et de flottants pour les types à virgule flottante.

Une fois que vous connaissez le format, vous pouvez le lire de manière portable. C'est un peu délicat à faire pour les entiers tout en évitant les débordements arithmétiques. C'est très difficile pour les valeurs à virgule flottante. Cependant, le site dispose d'un code qui vous permettra de lire les données à virgule flottante de façon portative.

Un fwrite() suivi d'un fread() fonctionnera jusqu'à ce que le compilateur modifie sa stratégie de mise en page de structure. Mais ça commence tout le temps à cause du passage à 64 bits.

https://github.com/MalcolmMcLean/ieee754