2010-03-04 4 views
2

J'ai regardé des objets binaires en lecture et en écriture en C++ mais j'ai des problèmes. Ça "marche" mais en plus je reçois une énorme sortie d'erreurs/"info".Échec d'exécution en lecture/écriture binaire

Ce que je l'ai fait est

Person p2; 

std::fstream file; 
file.open(filename.c_str(), std::ios::in | std::ios::out | std::ios::binary); 
file.seekg(0, std::ios::beg); 
file.read ((char*)&p2, sizeof(p2)); 
file.close(); 
std::cout << "Name: " << p2.name; 

personne est un struct simple contenant string name et int age. Quand je lance le programme, il sort "Nom: Bob" car j'ai déjà créé un programme pour écrire dans un fichier (donc l'objet est déjà dans le nom de fichier).

EN SUS pour produire le nom qu'il génère également:

* glibc détecté * programme: à double corruption gratuit og (de fastttop): ***

Backtrace:

...

carte mémoire:

...

Abandon

+1

Ne pas re-taper le code, il peut introduire des erreurs. __Couper et coller le code__. La lecture/écriture binaire d'un objet ne fonctionnera que si la structure ne contient aucun pointeur. Cette règle doit être appliquée de manière récursive à tous les membres.Donc, si un membre ou membre membre ou membre membre est un pointeur, cela va casser. Sans plus d'informations sur Person, il est difficile de dire si cela fonctionnera réellement. –

+0

Montrez-nous la déclaration de Personne. –

+0

Rappelez-vous qu'un compilateur est autorisé à insérer un remplissage entre les champs dans les structures, les classes et les syndicats. Un autre problème est que les chaînes doivent généralement avoir un espace alloué pour elles, lire dans cet espace, puis assigner à une structure, * à moins que le champ de texte ne soit de taille fixe *. –

Répondre

3

La chaîne de nom de la structure Person est-elle un tableau de caractères ou une chaîne STL? Vous ne pouvez pas remplir une chaîne STL en lisant des données binaires dessus, puisque le format de données n'est pas sérialisable (contient des pointeurs)

0

Soit p2.name est un char * et vous écrivez et lisez la valeur du pointeur , pas ce qui est pointé par cela. Ou p2.name est un type plus complexe tel que std :: string qui utilise des pointeurs internes avec le même problème.

Les classes de sérialisation nécessitent souvent plus de travail que le simple vidage de la représentation de la mémoire.

+0

mais si c'est char name [100], cela fonctionnerait probablement. –

0

Vous avez dit avoir écrit l'objet Personne dans un fichier. Avez-vous essayé d'utiliser un outil de vidage pour voir si ce que vous attendiez dans le fichier est ce que vous attendiez?

Avez-vous essayé d'utiliser une chaîne au lieu d'utiliser une chaîne, utilisez un caractère ordinaire (comme indiqué par @bdk)?

1

Il serait intéressant de voir comment vous écrivez les informations dans un fichier, ainsi que comment la structure Person est construite.
Si vous n'avez aucun problème que le fichier est en texte brut, ma suggestion serait d'écrire au fichier en utilisant string::c_str() (qui renvoie un const const *) ainsi qu'en utilisant itoa() ou itoa_s() pour obtenir l'entier en tant que char * .

Vous pouvez également avoir un ou plusieurs constructeurs en personne:

Person(const std::string& name, int age); 
Person(const char* name, int age); 

puis, lorsque vous extrayez les données du fichier que vous appelez simplement le constructeur avec ces données.

0

Lorsque vous utilisez des E/S binaires, la taille doit être fixée. Si vous utilisez une chaîne STL ici, cela posera un problème car la taille d'une chaîne STL est arbitraire.