IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Ecriture/Lecture d'un fichier binaire avec vector


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut Ecriture/Lecture d'un fichier binaire avec vector
    Bonsoir,
    je cherche désespérément à pouvoir écrire dans un fichier binaire (pour empêcher une édition trop simple)
    les informations d'une tilemap qui se trouvent dans un struct.

    Voici la structure:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct dataMap{
    	unsigned int mapX;
    	unsigned int mapY;
     
    	vector<vector<int>> dataTexture1;
    	vector<vector<int>> dataTexture2;
    	vector<vector<int>> dataCollision;
    	vector<vector<int>> dataEvent;
    };
    L'idée c'est que puisse définir la largeur et la hauteur de ma carte puis de définir les données de chaque tile
    dans un fichier texte. Cette étape est faite et fonctionne. Maintenant je n'arrive pas écrire dans le fichier binaire
    toute les informations puisque j'ai des tableaux dynamiques et encore moins à lire le fichier pour retrouver mon
    dataMap.

    Merci d'avance !

  2. #2
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 034
    Billets dans le blog
    12
    Par défaut
    Salut!
    Des vector de vector? Tu t'amuses bien toi!
    As-tu regardé du côté de Boost.Serialize pour ton problème?
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    J'utilise un vector de vector pour les deux dimensions (ça va simplifier mon code par la suite). Oui j'ai regardé un peu la sérialisation
    mais à vrai dire je n'es pas vraiment compris le principe et la syntaxe. Est-ce que la sérialisation est la seul solution ?
    Même si j'ai bien vu que l'utilisation de plusieurs vecteurs de vecteurs dans un même struct compliquait les choses ^^

  4. #4
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    Je ne suis pas sûr que d'avoir des vectors de vectors simplifie réellement ton code mais bon, il n'y a rien d'interdit!

    Quelles sont exactement les difficultés que tu rencontres pour écrire dans le fichier binaire? Je ne vois pas de rapport immédiat avec la question de l'allocation dynamique de la mémoire...

    Pour faire très simple, je verrais le schéma suivant:

    - un en-tête qui donnerait le nombre d'enregistrements,
    - chaque enregistrement commencerait par les 2*sizeof(size_t) octets contenant les dimensions du vecteur² à allouer,
    - puis viendraient les données elles-mêmes.

    Pour copier un vecteur d'int, c'est assez facile: fs.write( (char*) vec.data(), vec.size()*sizeof(int) );Copier un vecteur de vecteurs, là, c'est plus pénible parce qu'il faut répéter l'opération vec.size() fois.

    Pour la lecture, c'est à peu près la même chose à l'envers, mais il ne faut pas oublier d'allouer d'abord de la mémoire dans le vecteur de destination: vec v(size); fs.read(vec.data(), size*sizeof(int));Attention à bien utiliser RVO / move semantic / emplace_back pour éviter de faire trop de copies de tes données...

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Déjà, oublie les vector de vector, c'est inutilement compliqué contrairement à ce qu'on peut croire http://cpp.developpez.com/faq/cpp/?p...au-de-tableaux

    Citation Envoyé par herotom99 Voir le message
    Oui j'ai regardé un peu la sérialisation
    mais à vrai dire je n'es pas vraiment compris le principe et la syntaxe. Est-ce que la sérialisation est la seul solution ?
    Ben écrire dans un fichier ça s'appelle sérialiser à vrai dire.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Hum je veux bien utiliser des tableaux à deux dimensions classique mais le problème c'est que la taille de ma carte (XY)
    n'est défini que par l'utilisateur donc je n'es aucun moyen de connaître la taille de mon tableau pour la lecture du fichier :/

    Parce qu'au final, j'ai bien plusieurs tableaux dans un struct mais je dois pouvoir les déclarer sans connaître leur taille final... (d'où les vector).
    Donc déjà ça pose un problème.

    Ensuite, imaginons que j'ai réussi à définir la taille des tableaux que je voulais. Lorsque je vais vouloir lire mon fichier binaire pour retrouver mes tableaux
    je ne vais pas pouvoir puisque la taille du tableau dépend de l'utilisateur... C'est pour ça que j'avais mis appart la taille X et Y de ma map dans le struct.
    Sauf que lorsque je lis le fichier je lis toute la structure en même temps ! Donc je ne vois pas comment faire.

    Peut être faire deux fichiers avec l'un qui contient les tailles et un autres les valeurs ? mais c'est pas pratique ...

    mais sinon je suis bien d'accord qu'utiliser un vector de vector ça devient lourd :p

  7. #7
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    Utiliser des vectors c'est très bien. Des vectors imbriqués, c'est moins bien. Il suffit d'une fonction pour transformer l'adressage 2D en adressage 1D.
    Boost::serialize permet de sauvegarder des vectors dans des archives sans grande difficulté.
    Sinon, et c'est ce que je te proposais, place en début d'enregistrement sur 2*sizeof(size_t) octets les dimensions du tabeau, avant les données du vecteur elles-mêmes. Tu lis les dimensions, tu crées un vecteur de lignes*colonnes éléments pour réserver la mémoire et tu copies dedans les lignes*colonnes*sizeof(int) octets suivants du fichier.

  8. #8
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 034
    Billets dans le blog
    12
    Par défaut
    stendhal666 t'a donné la marche à suivre pour l'écriture et la récupération.
    Ensuite, personne n'a parlé d'utiliser des tableaux à 2 dimensions classiques, mais bien de remplacer tes vector< vector< truc > > par des vector< truc >
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Oui c'est ce que je vais faire (tout mettre en un seul tableau et grâce a une fonction et aux dimensions XY ,obtenir un tableau deux dimensions).
    Mais là je regarde surtout la sérialization de vector. sauf que je n'arrive pas vraiment à comprendre comment cela fonctionne (avec boost)

  10. #10
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21

  11. #11
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Bon, après avoir installé/build boost j'ai réécris une partie du code. J'arrive à écrire dans le fichier
    (le fichier ne fait pas 0 KB mais 1 KB ) par contre lorsque j'essais de lire le fichier je ne retrouve
    pas les bonnes valeurs :/
    Je précise que les valeurs rentrées sont X = 50, Y = 50 et les tableaux sont remplis de 50*50 fois 1.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    struct dataMap{
    	unsigned int mapX;
    	unsigned int mapY;
     
    	vector<int> dataTexture1;
    	vector<int> dataTexture2;
    	vector<int> dataCollision;
    	vector<int> dataEvent;
     
    	template <typename Archive>
    	void serialize(Archive& ar, const unsigned int version)
    	{
    		ar & mapX;
    		ar & mapY;
    		ar & dataTexture1;
    		ar & dataTexture2;
    		ar & dataCollision;
    		ar & dataEvent;
    	}
    };
     
    ----------------------------------------------------------------------
     
    bool EcrireMap(dataMap map)
    //Ecrire les informations dans le fichier binaire///
    {
    	//Trouve le fichier dans lequel écrire
    	string NomMap;
    	cout << "Nom de la map: ";
    	cin >> NomMap;
    	NomMap = "Map/" + NomMap + ".bin";
     
    	//Ecriture
    	ofstream fichier(NomMap.c_str());
    	boost::archive::binary_oarchive ofichier(fichier);
    	ofichier << map;
     
    	return true;
    }
     
    ----------------------------------------------------------------------------
     
    void readMap()
    //Lire le fichier binaire ciblé//
    {
    	//Cherche le fichier//
    	string NomMap;
    	cout << "Nom de la map: ";
    	cin >> NomMap;
    	NomMap = "Map/" + NomMap + ".bin";
     
    	//Lis le fichier
    	dataMap MAP;
    	ifstream fichier(NomMap.c_str());
    	boost::archive::binary_iarchive ifichier(fichier);
    	ifichier >> MAP;
     
    	//Simple test du fichier lu//
    	cout << MAP.mapX << endl;
    	cout << MAP.mapY << endl;
    }
    Ce que j'obtiens après la lecture:
    3435973836
    3435973836
    et pas mes deux 50.

  12. #12
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    On peut voir le code d'appel?

  13. #13
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    bool LoadFile(string filename,int X,int Y,vector<int> &dataTable)
    {
    	string pathfile = "MapFile/" + filename;
    	ifstream fichier;
    	fichier.open(pathfile,ios::beg);
    	if (fichier.is_open()) 
    	{
    		int nbVal = X*Y;
    		for (int i = 0; i < nbVal; i++)
    		{
    			vector<int> tableau;
    			int valeur;
    			fichier >> valeur;
    			dataTable.push_back(valeur);
    		}
    	}
    	else
    	{
    		return false;
    	}
    	fichier.close();
     
    	return true;
    }
     
    int GetInformation(dataMap &mapData)
    {
    	string dataTexture1File;
    	string dataTexture2File;
    	string dataCollisionFile;
    	string dataEventFile;
     
    	int m_mapX;
    	int m_mapY;
    	vector<int> m_dataTexture1;
    	vector<int> m_dataTexture2;
    	vector<int> m_dataCollision;
    	vector<int> m_dataEvent;
     
     
    	cout << "Largeur de la map: ";
    	cin >> m_mapX;
    	cout << endl;
    	if (m_mapX <= 0) return 1;
     
    	cout << "Hauteur de la map: ";
    	cin >> m_mapY;
    	cout << endl;
    	if (m_mapY <= 0) return 1;
     
    	//CHARGEMENT TEXTURE INFERIEUR//
    	cout << "Fichier de la texture inferieur: ";
    	cin >> dataTexture1File;
    	cout << endl << "Chargement du fichier ..." << endl;
    	if (LoadFile(dataTexture1File, m_mapX, m_mapY, m_dataTexture1))
    	{
    		cout << "Chargement du fichier reussi !" << endl << endl;
    	}
    	else 
    	{
    		return 2;
    	}
     
    	//CHARGEMENT TEXTURE SUPERIEUR//
    	cout << "Fichier de la texture superieur: ";
    	cin >> dataTexture2File;
    	cout << endl << "Chargement du fichier ..." << endl;
    	if (LoadFile(dataTexture2File, m_mapX, m_mapY, m_dataTexture2))
    	{
    		cout << "Chargement du fichier reussi !" << endl << endl;
    	}
    	else
    	{
    		return 2;
    	}
     
    	//CHARGEMENT COLLISION//
    	cout << "Fichier de collision: ";
    	cin >> dataCollisionFile;
    	cout << endl << "Chargement du fichier ..." << endl;
    	if (LoadFile(dataCollisionFile, m_mapX, m_mapY, m_dataCollision))
    	{
    		cout << "Chargement du fichier reussi !" << endl << endl;
    	}
    	else
    	{
    		return 2;
    	}
     
    	//CHARGEMENT EVENT//
    	cout << "Fichier des evenements: ";
    	cin >> dataEventFile;
    	cout << endl << "Chargement du fichier ..." << endl;
    	if (LoadFile(dataEventFile, m_mapX, m_mapY, m_dataEvent))
    	{
    		cout << "Chargement du fichier reussi !" << endl << endl;
    	}
    	else
    	{
    		return 2;
    	}
     
    	cout << "----------------------------------------------------" << endl;
    	cout << "TEXTURE INFERIEUR: " << dataTexture1File << endl;
    	cout << "TEXTURE SUPERIEUR: " << dataTexture2File << endl;
    	cout << "COLLISION: " << dataCollisionFile << endl;
    	cout << "EVENEMENT: " << dataEventFile << endl;
    	cout << "----------------------------------------------------" << endl << endl;
     
    	return 0;
    }
    Ne me tapez pas pour les copier/coller svp ;(
    Et sinon dans mon main() je crée juste un dataMap MAP auquel j'applique les informations GetInformation(MAP)

  14. #14
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    Euh... Il n'y a pas de sérialisation, ni de fichier binaire dans ce code, on est d'accord?
    Je pensais que c'était l'objet de la discussion et que tu voulais savoir pourquoi tu n'obtenais pas les bonnes valeurs avec une archive Boost?

  15. #15
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Hum, si non ? mon commentaire un peu plus haut:
    C'est comment j'écris en binaire avec la sérialisation de boost.
    Mon dernier commentaire c'est le reste du code (comment je
    lis les valeurs d'un fichier texte simple).

    J'ai peur de ne pas bien comprendre

  16. #16
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Je viens de voir que lorsque je sérialise mon fichier en text_oarchive j'obtiens la ligne suivante dans mon fichier:
    22 serialization::archive 14 0 0 3435973836 3435973836 0 0 0 0 0 0 0 0
    On retrouve bien mes valeurs étrange donc c'est bien lorsque j'écris dans le fichier qu'il y a un problème.

  17. #17
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    D'accord, mais comme il y a plus de chances que le problème vienne de ton code que de boost, je voulais voir comment, à quel moment, avec quelles variables tu appelais la fonction de sérialisation.
    Sans ça, je n'ai pas trop d'idée de ce qui peut se passer...
    A part ça, joyeux Noël!

  18. #18
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Bon et bien en réalité tout fonctionnait bien. Le problème c'est que j'avais oublié bêtement d'appliquer ma lecture (fonction loadMap) à mon struct dataMap. De ce fait
    les vectors et mes deux variables étaient vides. Lorsque je lisais la map cela m'affichait pas le contenu de la variable (puisqu'elle était vide) mais l'emplacement de ma
    mémoire allouée ... Donc j'ai corrigé l'erreur et tout fonctionne parfaitement maintenant

    En revanche, chose à noter lorsque je sérialiser en binary_oarchive, le fichier est deux fois plus lourd qu'en text_oarchive. Après peut être que la lecture sera plus rapide
    je sais pas ^^ en tout cas il faut juste que le fichier ne soit pas éditable facilement !

    Merci beaucoup pour votre aide, ça fait plaisir de voir autant de personne qui rendent service ! Joyeux noël

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture de fichiers binaire avec Get
    Par NVCfrm dans le forum Contribuez
    Réponses: 0
    Dernier message: 26/07/2013, 03h42
  2. Réponses: 5
    Dernier message: 05/08/2011, 11h36
  3. Réponses: 4
    Dernier message: 25/05/2011, 15h38
  4. Réponses: 2
    Dernier message: 01/03/2010, 12h50
  5. Lecture fichier binaire avec fLit
    Par kinouseb dans le forum WinDev
    Réponses: 4
    Dernier message: 06/07/2007, 23h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo