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 :

Écriture et lecture dans un fichier ouvert en mode binaire


Sujet :

C++

  1. #1
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut Écriture et lecture dans un fichier ouvert en mode binaire
    Je teste un peu le C++, et j'obtiens à la compilation :

    *** Error in `/home/jessie/workspace/c++-002/Debug/c++-002': double free or corruption (fasttop): 0x00000000023f9260 ***

    Je cherche et je n'ai pas encore le recul pour comprendre l'erreur.

    Voici les sources si quelqu'un peut m'aider à comprendre ce serait sympa.
    Je suis sous GNU Debian Linux et j'utilise Eclipse et le compilateur GCC.

    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
    #include <iostream>
    #include <cmath>
    #include <fstream>
     
    #include "Adresse.h"
     
    using namespace std;
     
     
     
    int main()
    {
    	char file[26] = "Essai";
     
    	ofstream monFlux(file, ios::binary);
    	if(monFlux)
    	{
     
    	}
    	else
    	{
    	cout << "Erreur" << endl;
    	}
     
     
    Adresse Personne1(102, "Charles", 1990, 26);
    Adresse Personne2(100, "Inconnu", 1900, 0);
     
    monFlux.write((char *) &Personne1, sizeof Personne1);
    monFlux.close();
     
    	ifstream lire(file, ios::binary);
     
     
    	lire.read((char *) &Personne2, sizeof Personne2);
    	if(lire)
    		{
     
    		}
    		else
    		{
    		cout << "Erreur" << endl;
    		}
     
     
    Personne1.Lecture_Attribut();
    Personne2.Lecture_Attribut();
     
    lire.close();
     
     
    }
    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
    #ifndef ADRESSE_H_
    #define ADRESSE_H_
     
    #include <iostream>
    #include <string>
     
    class Adresse
    {
     
    public:
     
    	// Constructeur par defaut
    	Adresse();
     
    	// Constructeur
    	Adresse(	signed int vi_cle,
    				std::string string_nom,
    				signed short vs_annee,
    				signed short vs_age	);
     
     
    	void Lecture_Attribut();
     
    	~Adresse();
     
    private :
     
    	signed int mvi_cle;
    	std::string mstring_nom;
    	signed short mvs_annee;
    	signed short mvs_age;
     
     
    };
    #endif /* ADRESSE_H_ */
    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
    #include "Adresse.h"
     
    // Constructeur par defaut
    Adresse::Adresse()
    {
    	mvi_cle = 0;
    	mstring_nom = "Inconnu",
    	mvs_annee = 0,
    	mvs_age = 0;
    }
     
    // Constructeur
    Adresse::Adresse(	signed int vi_cle, std::string string_nom, signed short vs_annee, signed short vs_age ) :
    										mvi_cle(vi_cle),
    										mstring_nom(string_nom),
    										mvs_annee(vs_annee),
    										mvs_age(vs_age)
    {
     
    }
     
    // Destructeur par Defaut
    Adresse::~Adresse()
    {
    	// TODO Auto-generated destructor stub
    }
     
    // Methode Lecture Attribut
    void Adresse::Lecture_Attribut()
    {
    	std::cout << mvi_cle << "\n";
    }

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Cette erreur survient en général quand on libère la mémoire pointée (par un pointeur non null) mais déjà libérée.

    L'une des façons les plus courante d'y parvenir, c'est de copier un pointeur dans un constructeur par copie (par exemple, généré par le compilateur), et qu'on détruit le pointé dans le destructeur.

    Dans le code que tu montres, je ne le vois pas.
    Utilise un débuggeur, pour trouver dans quel destructeur ce produit l'erreur.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre éprouvé Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Points : 1 054
    Points
    1 054
    Par défaut
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Adresse Personne2(100, "Inconnu", 1900, 0);
     
    monFlux.write((char *) &Personne1, sizeof Personne1);
    monFlux.close();
     
    	ifstream lire(file, ios::binary);
     
     
    	lire.read((char *) &Personne2, sizeof Personne2);
    Cette partie du code me semble douteuse. La fonction membre read requiert un char *, il faut lui fournir un vrai char *. Caster un pointeur objet en char * ne converti pas l'objet, juste le pointeur. Ton problème vient de ce que la fonction read, de par cette conversion "douteuse" considère la zone mémoire de l'objet de type adresse comme une suite de caractère. Il écrase donc les données spécifique de Personne2 avec des char. Et quand l'objet est détruit, les membres qui contiennent des données incohérentes vont accéder à des zones mémoires interdites.

    La bonne pratique consiste à créer un buffer (ici un tableau de char) que tu passes à la fonction lire puis transférer ce buffer à ton objet par la fonction qui va bien (qui dans ton cas n'existe pas encore, tu dois donc la rajouter à ta classe Adresse). Tu peux aussi utiliser une fonction qui utilise un std::string à la place d'un buffer (cf ::getline) que tu passeras à ton objet. Avec cette deuxième méthode tu n'as pas à te préoccuper de la taille des données reçues, string se charge de tout.


    Bonne chance.

  4. #4
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Je doute que tu obtiennes ça à la compilation, c'est une erreur à l'éxécution.
    Tes read et write avec cast en char* sont bien cavaliers et devraient être modifiés avant toute chose.
    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.

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Wow. On dirait du C, où l'on pouvait se permettre de lire et écrire des structures complètes directement dans un fichier binaire... à condition de savoir ce que l'on faisait.

    En C++, cette approche ne passe pas avec les classes modernes. Il faut faire soi-même la sérialisation des données, et C++ préfère fortement les fichiers texte aux fichiers binaires.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    N'allons pas aussi loin, les fichiers binaires sont tout autant utiles et utilisés en C++.
    Ton programme affiche ce que tu attends avant de planter ? Que Personne1 et Personne2 ont les mêmes infos ?
    A priori, l'erreur vient à la destruction de Personne2.
    Avec ton mauvais write, ce que tu écris dans le fichier ne correspond pas à grand chose, surtout pour le nom(? je suppose, on ne sait absolument rien de ton Adresse). A vue de nez tu chopes au mieux le pointeur vers la string interne. Quand tu read, tu donnes ce pointeur à Personne2, et quand chacun le détruit, ça crash.
    C'est dommage d'utiliser des fstream pour en faire un truc aussi moche. Pour utiliser fstream et (dé)sérialiser une classe, on surcharge les opérateur >> et <<.
    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.

  7. #7
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut
    Effectivement c'est à l'execution et non à la compilation ce message d'erreur.

    Oui c'est façon C que j'ai voulu copier des blocs d'un coup.

    Je travail le C++ mais je sature. Le livre de de jesse liberty le langage C++ et pas tres fournis sur le travail avec les fichiers.
    Son exemple et fourni tel quel je l'ai moi meme ecris.

    J'ai besoin de comprendre, je mis prend mal pour l'instant.
    Oui j'ai ce que je veux, personne2 contient bien personne1.

    Le debugger m'amene bien sur string.

    Merçi pour ses explications rapides.

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    En fait, si on regarde plus un tout petit peu ta classe Adresse (que je reproduis ici)
    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
    class Adresse
    {
     
    public:
     
    	// Constructeur par defaut
    	Adresse();
     
    	// Constructeur
    	Adresse(	signed int vi_cle,
    				std::string string_nom,
    				signed short vs_annee,
    				signed short vs_age	);
     
     
    	void Lecture_Attribut();
     
    	~Adresse();  // (*)
     
    private :
     
    	signed int mvi_cle;
    	std::string mstring_nom;
    	signed short mvs_annee;
    	signed short mvs_age;
     
     
    };
    on se rend compte que tu n'auras aucun problème en essayant de sérialiser les membres mvi_cle, mvs_annee et mvs_age, parce que ce sont des types primitifs (enfin, oui, tu risques d'avoir un problème au niveau du boutisme, mais soit).

    Par contre, la classe std::string n'est pas ce qu'il convient d'appeler un type POD (Plain Old Data type)! car elle s'occupe elle-même de gérer la mémoire nécessaire à la représentation de l'ensemble des caractères qui la composent. Et ca, ca va forcément quelques soucis au niveau de l'écriture dans un fichier binaire, car... si la taille de la chaine de caractères est connue de la chaine, et si on peut s'arranger pour que la chaine de caractères écrite dans le fichier soit terminée par un '\0' qui représente la fin de la chaine en question au sein de ton ficher, il n'empêche que la taille de ta structure Adresse ne correspond pas forcément... à la taille des données qu'elle contient.

    Je m'explique:

    Si tu demande d'afficher la taille de ta classe Adresse, tu obtiendra toujours la même valeur, car sizeof(quelque chose) correspond à une constante de compilation. Si bien que, de mon coté, un sizeof(Adresse) me donne une valeur égale à 48 bytes, et, si je demande d'afficher la taille des différents types qui composent cette structure (à savoir signed int, signed short et std::string), j'obtiens
    • 4 bytes pour signed int
    • 2 bytes pour signed short et
    • 32 bytes pour std::string

    (ce qui implique que, sur mon pc, il y a 8 bytes de "padding" rajoutés ici ou là )
    Mais, si je crées une variable de type Adresse sous la forme de Adresse a2(2,"une très très longue chaine pour dire Salut la compagnie",1998,15); et que je demande d'afficher la taille de cette structure à l'aide de sizeof(a2), j'obtiendrai aussi ... 48, alors que rien que mstring_nom est composé de... 56 caractères!

    Pourquoi me demanderas-tu ? hé bien, tout simplement parce que la classe std::string est composée, entre autres, d'un pointeur sur char dont l'adresse sera définie à l'exécution afin de correspondre à un espace mémoire suffisant pour contenir tous les caractères qui le composent. Et un pointeur sur char, ça a une taille clairement déterminée (qui, au passage, est la même pour tous les types que l'on rencontre, vu qu'il s'agit de la taille "suffisante pour représenter n'importe quelle adresse en mémoire").

    Maintenant que je t'ai expliqué le problème auquel on est confrontés on peut essayer d'y apporter une solution. Par exemple, en créant une fonction qui s'occupera d'écrire exactement les données qui nous intéressent dans notre fichier, sous une forme qui pourrait être proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void writeBinary(Adresse const & adr, std::ofstream & ofs){
        ofs.write(reinterpret_cast<char *>(&(adr.mvi_cle)), sizeof(signed int));
        ofs.write(reinterpret_cast<char *>(&(adr.mstring_nom.size(),sizeof(size_t)); // sauvegardons la taille de la chaine de caractères
        ofs.write(adr.mstring_nom.c_str(), adr.mstring_nom.size()); // std::string.c_str() renvoie une chaine de caractères "C style" (terminée par '\n')
        ofs.write(reiterpret_cast<char *>(&(adr.mvs_annee),sizeof(signed short));
        ofs.write(reiterpret_cast<char *>(&(adr.mvs_age),sizeof(signed short));
    }
    et, pour la lecture, nous pourrions envisager un fonction proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Adresse readBinary(std::ifsream & ifs){
       signed int id;
       size_t tailleNom;
       signed short annee;
       signed short age;
       ifs.read(reinterpret_cast<char*>(&id),sizeof(signed int));
       ifs.read(reinterpret_cast<char*>(&tailleNom),sizeof(size_t));
       std::unique_ptr<char> cstr= std::make_unique<char[]>(tailleNom+1);
       ifs.read(crtr.get(),taillenom+1);
       ifs.read(reinterpret_cast<char *>(&annee),sizeof(signed short));
       ifs.read(reinterpret_cast<char *>(&age), sizeof(signed short));
       return Adresse(udn csrt.get(),annee,age);
    }
    (ATTENTION!!! code non testé!!!)

    Cependant, il faut bien être conscient d'une chose: A moins d'imposer un nombre de caractères arbitraires pour représenter la donnée membre mstring_nom, il te sera très difficile de mettre en place un moyen efficace pour voyager parmi les adresses enregistrées dans le fichier. En effet, à moins d'avoir recours à la technique dite des "fichiers indexés", il te sera impossible de définir l'offset auquel commencent les différentes données .

    En outre, l'un des principaux attraits à l'utilisation d'un fichier binaire est le fait qu'il est (plus ou moins) possible d'écraser les données "obsolètes" d'une donnée avec les données "mise à jour". Mais cela implique que la taille des données enregistrée soit strictement constante. Encore une fois, le fait qu'une std::string n'impose aucune taille particulière rend ce genre de comportement totalement impossible à mettre en place, à moins, encore une fois, d'imposer un nombre de caractères bien particulier pour la représentation du nom

    (*) Au passage: ton destructeur ne fait absolument rien que le destructeur fournit par défaut par ton compilateur ne ferait... Tu te fais donc sans doute beaucoup de mal pour rien en te faisant ch...er à le définir toi-même

    Enfin, mais ce n'est qu'un avis perso, la notation hongroise n'apporte pas vraiment grand chose à ton code. Pourquoi ne renommerais tu pas tes membres de manière plus simple, sous la forme (par exemple) de m_id, m_nom, m_annee et m_age (même si je n'aime pas trop ce genre de convention, on la retrouve assez souvent pour qu'elle soit conseillée )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut
    Merçi à tous pour le temps prit à répondre.

    " koala01"
    Ton explication m'a bien aider à comprendre. J'y avais pensé et voulais utilisé un tableau à taille fixe mtc_nom[26+1]. Mais je me suis heurter à une incompatibilité avec "strncpy" pour transférer ce tableau dans un autre.
    Je ne maîtrise pas encore, je continu mon apprentissage.

    Je vois bien ou sont mes erreurs.

    Pour le style hongrois j'assume, je me repère mieux comme ça.

  10. #10
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par debut_c Voir le message
    Merçi à tous pour le temps prit à répondre.

    " koala01"
    Ton explication m'a bien aider à comprendre. J'y avais pensé et voulais utilisé un tableau à taille fixe mtc_nom[26+1]. Mais je me suis heurter à une incompatibilité avec "strncpy" pour transférer ce tableau dans un autre.
    Humm... avant de vouloir imposer une taille précise pour une chaine de caractères, il faut vraiment arriver à donner une réponse convaincante à deux questions :
    1. ne risque-t-on pas de se retrouver avec énormément de chaines de caractères (beaucou, même si c'est très relatif avec 26+1) plus courte, et donc de perdre énormément de place et
    2. ne risque-t-on pas, à l'inverse, de justement se trouver régulièrement dans une situation dans laquelle cette taille imposée risque de ne pas suffire (une seule fois sera assez embêtante ) :question

    Par contre, il ne faut pas oublier que strncpy est une fonction... issue du C, et qu'elle ne fonctionne donc... qu'avec des chaines de caractères "C style" (avec tout ce que cela implique)... A priori, et bien que je ne cautionnerai jamais de le faire, si tu avais utilisé une chaine C style, même et surtout si elle est de taille fixe, tu n'aurais surement pas eu de problème

    Mais je le répète : je ne cautionnerai jamais le fait d'utiliser un chaine de caractères C style

    Dans le pire des cas, std::array pourrait t'aider "pas mal" dans l'idée de manipuler des chaines de caractères de taille fixe
    Je ne maîtrise pas encore, je continu mon apprentissage.
    Je vois bien ou sont mes erreurs.

    Pour le style hongrois j'assume, je me repère mieux comme ça.
    Ben, si au moins tu utilisait les "bonnes" convention dans ta notation hongroise, nous pourrions nous "contenter" de dire que c'est inutile!

    Mais en utilisant mvs et mvi, cela ne nous aide pas vraiment à déterminer le type de la donnée que l'on manipule

    il n'y a au final que mstring_* qui ne pose pas trop ce problème Alors, de l'inutile et mal fait, ca mérite vraiment d'être signalé, ne serait-ce que pour que tu reconsidères le choix de tes conventions (à défaut d'oublier ce style de notation pour l'instant )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. lecture et écriture de données dans un fichier
    Par follichon dans le forum C
    Réponses: 1
    Dernier message: 24/11/2011, 12h17
  2. Problème lecture écriture par bloc dans un fichier
    Par scary dans le forum Débuter
    Réponses: 5
    Dernier message: 22/04/2009, 19h28
  3. [POI] Problème écriture/lecture dans un fichier Excel
    Par steuve dans le forum Documents
    Réponses: 6
    Dernier message: 02/07/2007, 15h47
  4. écriture/lecture dans des fichiers
    Par rafale001 dans le forum C
    Réponses: 14
    Dernier message: 02/03/2007, 16h59
  5. Réponses: 12
    Dernier message: 14/06/2004, 13h06

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