Fstream, >> et <<

Roro8883 Messages postés 70 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 1 février 2008 - 20 sept. 2007 à 14:59
LostInGeekLand Messages postés 1 Date d'inscription jeudi 24 juillet 2008 Statut Membre Dernière intervention 24 juillet 2008 - 24 juil. 2008 à 17:39
Bonjour à tous !

J'ai un problème dans mon code avec la fonction fstream.
Ca fait depuis un moment que je suis dessus et je trouve pas le problème.
Si quelqu'un pouvait m'aider ....

   fstream hfile;                           

   hfile.open(file.c_str(), ios::in | ios::out);
     
         /* Modification  */
      // Lecture du fichier jusqu'à la la ligne précédent la ligne recherchée
   int x = 0;
   while ((!hfile.eof()) && (x != meter))
   {
      hfile >> line;
      x++;
   }

      // Modification
   hfile << value << "\n";

         /* Fermeture du fichier */
   hfile.close();

Voilà mon code, et le problème est que les lignes sont bien lues dans le fichier, mais impossible d'y écrire quelque chose !
Je pense que c'est parce que je mets les >> et << à la suite, mais je vois pas pourquoi ça poserait problème.

Qi quelqu'un pouvait m'aider ... parce que ça fait à peu près 2H que je suis dessus !

Merci

10 réponses

The_Guardian Messages postés 317 Date d'inscription vendredi 25 mai 2007 Statut Membre Dernière intervention 19 octobre 2007 1
20 sept. 2007 à 16:26
Bonjour,

Je ne suis pas sure que l'ecriture dans un fichier soit aussi facile et je serais toi, j'ouvrirais le fichier A en lecture et je creerais un fichier B en ecriture et ensuite toutes les lignes lues de A sont recopiees dans B sauf la ligne que tu veux changer
 et apres tu ecris jusqu'a la fin et tu renommes B en A et c'est ok
car je vois pas trop comment ca va faire si l'ancienne ligne L1 est remplacee par une nouvelle ligne L2 plus longue
mais bon peut-etre que fstream gere tout ca tout seul deja  mais ca me parait assez etrange enfin voila ce que je te propose de faire
=

Une autruche ne se cuit pas aux petits lardons
0
Roro8883 Messages postés 70 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 1 février 2008
20 sept. 2007 à 17:19
Ben on voit sur plein de site qu'on peut ouvrir un fichier texte en lecture et écriture simultanément avec fstream ...
Donc j'ai tenté, mais ça marche pas !
J'sais pas pourquoi...

J'ai presque réussi en utilisant :
    long place = hfile.tellg();
    hfile.seekp (place-1);
mais ça ne fonctionne que pour des chaines de mêmes taille (et encore ...).

Donc je pense que je vais faire comme tu dis.
J'voulais faire un truc plus simple, mais en fait ça marche pas (j'vois pas à quoi ça sert alors fstream !).

Tant pis, merci quand même !
0
Roro8883 Messages postés 70 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 1 février 2008
20 sept. 2007 à 17:59
Le problème c'est que souvent le fichier contient plein de données (pleins de lignes de texte).

Et donc lire et recopié entièrement le fichier prend pas mal de temps ... ce que je voudrais absolument éviter !

Existe-t-il un moyen (facile ou non [enfin pas super dur non plus]) pour modifier une ligne de texte dans un fichier sans avoir besoin de la recopier ?!
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 sept. 2007 à 19:13
Comment veux tu te positionner à la ligne voulu si tu ne le lis pas en entier ?
On peut éviter de recopier ce qui précède la ligne mais pas se qui suit (si les tailles ne sont pas identique).

Voici un exemple vite fait:

int main(void)
{
    char *lpBuf;
    char lpNewLine[] = "Ceci est une ligne de remplacement\r\n";
    int iSize;
    fstream fsFile("d:\\test.txt", ios::in|ios::out|ios::binary);

    fsFile.seekg(0, ios::end);
    iSize = fsFile.tellg();
    fsFile.seekg(0, ios::beg);

    lpBuf = new char[iSize+1];

    fsFile.read(lpBuf, iSize);
    lpBuf[fsFile.gcount()] = 0;
    int iLast 0, iCur 0;
    int iLine = 5; // On remplace la 5 ème ligne

    do {
        if(lpBuf[iCur] == '\n' || !lpBuf[iCur]) {
            if(!--iLine) {
                fsFile.seekg(iLast, ios::beg);
                fsFile.write(lpNewLine, sizeof(lpNewLine)-1);
                if((iCur-iLast)+1 != sizeof(lpNewLine)-1)
                    fsFile.write(&lpBuf[++iCur], (iSize-iCur));
                break;
            }
            iLast = iCur+1;
        }
    } while(lpBuf[iCur++]);

    delete[] lpBuf;
               

    return 0;
}

C++ (@++)<!--
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Roro8883 Messages postés 70 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 1 février 2008
20 sept. 2007 à 20:51
Oui, avant d'appeller le code que j'ai mis dans mon premier post, je lis d'abord le fichier (presque en entier) pour enregistrer le numéro de la ligne à modifier (dans la variable 'meter').

Et sinon, le vrai problème c'est que les fichiers sont trop gros.
Rien que cette ligne :
    lpBuf = new char[iSize+1];
J'imagine même pas la quantité de mémoire que ça utiliserait, même si après la mémoire est libérée...

Enfin, si je comprends bien, y'a aucune fonction, classe ou autre chose qui permette de modifier le texte (d'un fichier texte) comme on ferait simplement en l'ouvrant avec un éditeur de texte ?!
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 sept. 2007 à 21:04
Un éditeur de texte met tout le fichier en mémoire (ou une partie, dépendant de l'éditeur). Les modifications sont faites en mémoire et réintégrées dans le fichier à la fin.

Si ton fichier est vraiment trop gros, il faudra le charger en mémoire par bloques.
Sinon, j'aimerais bien savoir qu'elle taille a ce fichier, car un fichier texte n'est, normalement, pas supposé être si gros.

C++ (@++)<!--
0
Roro8883 Messages postés 70 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 1 février 2008
20 sept. 2007 à 21:15
C'est pas vraiment un fichier texte ... enfin si mais c'est plus présenté comme une base de données.

C'est un fichier qui contient des séquences d'ADN, et pleins d'autres trucs du genre.
Donc ça prend de la place !

Sinon, les logiciels de base de données, ils font comment, ça fonctionne pareil que les éditeur de texte (mise en mémoire par bloc) ?
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 sept. 2007 à 21:36
J'ignore comment sont conçu les BDD mais ça m'étonnerais énormément.

C++ (@++)<!--
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
22 sept. 2007 à 12:09
Ca prend énormément de place surtout si tu utilises un fichier au format texte. Un fichier binaire te fera économiser énormément de place (4 fois moins de mémoire), et c'est tellement plus rapide en lecture et tellement plus simple à manipuler par programme. Evidemment c'est illisible avec un éditeur de texte.

Avec un format binaire, tu te positionnes à l'emplacement ou tu veux écrire des données. Toutes les données restantes dans le fichier doivent être décalé pour pouvoir y intercaler tes données. L'intérêt c'est que ce décalage peut s'effectuer par bloc (comme on ferait pour un fichier texte), et donc meme si ton fichier est énorme, tu peux simplement décaler par bloc de quelques dizaines de ko.
0
LostInGeekLand Messages postés 1 Date d'inscription jeudi 24 juillet 2008 Statut Membre Dernière intervention 24 juillet 2008
24 juil. 2008 à 17:39
Bonjour,

je viens de tomber sur cette conversation et ça m'interesse bcp,
en effet j'enregistre pour ma part un fichier de la manière suivante :

std::ofstream oFile( outputFname.c_str(), std::ios::out | std::ios_base::trunc );

Et ça me génère un fichier texte. J'aimerai plutôt un fichier binaire, pour éviter les risque d'erreurs à la relecture.
luthor c'est justement ce que tu proposais .. masi comment on fait pour spécifier que l'on veut que le fichier de sortie soit binaire ???

faire

std::ofstream oFile( outputFname.c_str(), std::ios::out | std::ios_base::binary );
ne semble pas être la solution

Merci
0
Rejoignez-nous