fichier txt : tellg() ne me retourne pas de bonnes valeurs
bonjour,
Je suis sous WindowsXP et je travaille avec BorlandC++ 6 Professionnal.
J'ai un sérieux souci avec un fichier texte. :bug:
Plus précisément avec des \n à la position 4096 et 4097 de ce fichier texte. A cause de ces caractères, la fonction tellg() ne me retourne pas de bonnes valeurs.
Pour être sûr que cela ne venait pas de mon fichier, je génère un fichier txt avec un contenu aléatoire et en imposant un \n lorsque j'arrive au 4096 et 4097 caractères. J'utilise les codes ASCII compris entre 32 (espace) inclus et 127 (supprimer) exclus.
J'ai mis dans ma fenêtre 1 TStringGrid, un bouton (BtnOuvrir) et un composant OpenDialog (OpenDialog1).
Code:
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
|
TfFichier *fFichier;
//---------------------------------------------------------------------------
__fastcall TfFichier::TfFichier(TComponent* Owner)
: TForm(Owner)
{
StringGrid1->ColWidths[0] = 500;
StringGrid1->ColWidths[1] = 40;
StringGrid1->ColWidths[2] = 40;
GenereFichier();
}
//---------------------------------------------------------------------------
void __fastcall TfFichier::BtnQuitterClick(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TfFichier::GenereFichier()
{
int i, n;
int min, max;
min = 0;
max = 127;
srand(time(NULL));
ofstream Fichier("texte.txt", ios::out);
for (n=0; n<5000; n++)
{
i = (int) (min + ((float) rand() / RAND_MAX * (max - min + 1)));
if (n==4095 || n==4097 || n==4096)
{
Fichier<<endl;
}
else
{
if (i>=32 && i<127)
{
Fichier<<char(i);
}
else
{
Fichier<<endl;
}
}
//Fichier.flush();
}
Fichier.close();
}
//---------------------------------------------------------------------------
void __fastcall TfFichier::BtnOuvrir1Click(TObject *Sender)
{
AnsiString nom, valeur;
char buffer[4097];
int n, i;
unsigned char data;
if (OpenDialog1->Execute())
{
nom = OpenDialog1->FileName;
this->Repaint();
Label1->Caption = nom;
StringGrid1->Cols[0]->Clear();
StringGrid1->Cols[1]->Clear();
StringGrid1->Cols[2]->Clear();
StringGrid1->RowCount = 2;
ifstream Fichier(nom.c_str());
n = 0;
i = 1;
while (!Fichier.eof() && Fichier.good())
{
Fichier.getline(buffer, sizeof(buffer), '\n');
n = n + strlen(buffer) + 2;
StringGrid1->Cells[0][i] = buffer;
StringGrid1->Cells[1][i] = IntToStr(n);
StringGrid1->Cells[2][i] = IntToStr(Fichier.tellg());
i++;
StringGrid1->RowCount ++;
}
Fichier.close();
}
} |
n'oubliez pas d'inclure
Code:
1 2 3
|
#include <fstream.h>
#include <time.h> |
pour la fonction random et pour les ifstream et ofstream.
------------------------
Dans le second RichEdit il y a 2 colonnes de chiffres :
- le premier chiffre est la somme des longueur des chaines récupérées (j'ai ajouté 2 pour tenir compte du \n en fin de ligne) ;
- le second chiffre est la valeur retournée par tellg().
Regardez les 2 colonnes de valeurs dans le RichEdit2 : il y a un écart de 1 au moins jusqu'au 4096ème caractère entre la valeur de gauche et la valeur de droite.
Si vous faites un fichier plus petit (moins de 4096 caractères dans la fonction GenereFichier), le problème ne se pose plus ou si vous supprimez ce test
Code:
1 2 3
|
if (n==4097 || n==4096) // j'impose un retour chariot ici
Fichier<<endl; |
plus de problème non plus (à moins que la valeur de i soit inférieure à 32 à ce moment).
Comment je peux corriger ce problème ? Sachant que je dois utiliser ifstream et ofstream.
:merci: à vous
[edit]
j'ai modifié le code : j'utilise un TStringGrid au lieu des RichEdit : on peut plus facilement repérer les lignes qui posent problème (les valeurs de tellg() et calculées et le contenu de chaque ligne du fichier se trouvent sur la même ligne du TStringGrid).
[/edit]
fichier txt : tellg() ne me retourne pas de bonnes valeurs
bonjour
je pense que tellg() te donne la bonne valeur , c'est plutôt le calcul fait par le compilateur builder c++ 6 qui comptabilise un caractère pour \n alors qu'il met 0D + 0A soit deux caractères de plus il faut aussi voir si alignement des données se fait en B ,W ,DW ,QW
dans ton exemple il faudrai éliminer le chr(10) et chr(13) pour éventuellement ne pas parasiter le résultat
j'espère t'avoir aider de mes petites possibilités
jpf