OVH Cloud OVH Cloud

Visual C++ 6.0 ; debug ; fichier

29 réponses
Avatar
Laurent
c'est simple, ce programme fonctionne normallement sans debug, et en debug,
il me trouve un eof() des le premier input.read()


JE NE COMPRENDS PAS !!!!!!!!!!!

merci.


#include <iostream.h>
#include <fstream.h>
#include <stdio.h>

void main(void)
{

ifstream input;
char Carac[1];
int Taille;

input.open("fichier.txt",ios::in);

do
{
input.read(Carac, sizeof(Carac));
if(input.good())
{
Taille++;
}
}
while(!input.eof());

cout << "Taille : " << Taille << " octets.";


}

10 réponses

1 2 3
Avatar
Thomas Abbé
si tu veux avoir la taille dun fichier,
regarde dans la documentation sous "seek"
thomas

"Laurent" schrieb:
c'est simple, ce programme fonctionne normallement sans debug, et en
debug,

il me trouve un eof() des le premier input.read()


JE NE COMPRENDS PAS !!!!!!!!!!!

merci.


#include <iostream.h>
#include <fstream.h>
#include <stdio.h>

void main(void)
{

ifstream input;
char Carac[1];
int Taille;

input.open("fichier.txt",ios::in);

do
{
input.read(Carac, sizeof(Carac));
if(input.good())
{
Taille++;
}
}
while(!input.eof());

cout << "Taille : " << Taille << " octets.";


}




Avatar
Loïc Joly
Thomas Abbé wrote:

si tu veux avoir la taille dun fichier,
regarde dans la documentation sous "seek"


Ca ne donnerait pas grand-chose : La valeur retournée par un seek n'a
pas forcément le moindre lien avec la taille (ni même avec un nombre, je
crois ?)
--
Loïc

Avatar
Thomas Abbé
oui et non.

FILE *f
fseek(f,0,SEEK_END);
int filesize = ftell(f);

et voila ;)

thomas


"Loïc Joly" schrieb:
Thomas Abbé wrote:

si tu veux avoir la taille dun fichier,
regarde dans la documentation sous "seek"


Ca ne donnerait pas grand-chose : La valeur retournée par un seek n'a
pas forcément le moindre lien avec la taille (ni même avec un nombre, je
crois ?)
--
Loïc





Avatar
Régis Troadec
Salut,

"Laurent" a écrit dans le message de news:
btk39j$l34$
c'est simple, ce programme fonctionne normallement sans debug, et en
debug,

il me trouve un eof() des le premier input.read()


JE NE COMPRENDS PAS !!!!!!!!!!!

merci.



le "ça marche pas en debug mais autrement oui" sous Visual reste vague dans
ton post : qu'entends-tu par là ? Lances-tu l'exécutable du dossier de la
version debug (par rapport à celui de la release), auquel cas "fichier.txt"
n'y est peut-être pas présent ?

#include <iostream.h>
#include <fstream.h>
#include <stdio.h>


headers superflus :
#include <iostream.h> => inclus avec fstream
#include <stdio.h> => bon pour les E/S C, pas ici

void main(void)
{

ifstream input;
char Carac[1];
int Taille;


Taille non initialisée => int Taille = 0;
char Carac[1] pas très élégant => char Carac; // voir plus loin
ouverture de flux plus simple (ios::in est par defaut) => ifstream
input("fichier.txt"); // open à virer en dessous

input.open("fichier.txt",ios::in);

do
{
input.read(Carac, sizeof(Carac));
if(input.good())
{
Taille++;
}
}
while(!input.eof());


=> Tester si flux bien ouvert avant et prevoir une gestion sinon:
=> get (lit 1 caractère) plus facile que read (utilisé plutôt pour flux
binaire), sinon => input.read(&Carac, sizeof(Carac));
=> test dans boucle peu élégant

Je te propose :

if( input ) {
while ( input.good() ) { // tt que eof non atteinte ou pas
d'erreur
input.get( Carac ); // lit 1 caractere
Taille++; // incr
}
}
else {
cout << "blabla..." << endl;
}


cout << "Taille : " << Taille << " octets.";


}




Et voilà.

Avatar
Michel Michaud
Dans news:btkri2$3g5$, Régis
Je te propose :

if( input ) {
while ( input.good() ) { // tt que eof non atteinte
ou pas d'erreur
input.get( Carac ); // lit 1 caractere
Taille++; // incr
}


Ça c'est à peu près certain de ne pas fonctionner. Il faut tester
après le get pour savoir si un caractère a été lu.

La technique de lecture en C++ (et en fait, c'est similaire en C)
a été montrée de nombreuses fois ici. Rappelons-la symboliquement :

while ( lecture ) // Combinaison de lecture et de test
{ // de la réussite
on a réussi à lire, on peut utiliser la donnée lue
}

Par exemple ici :

while (input.get(carac))
++taille;

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
Régis Troadec
C'est vrai et ta solution est plus commode.

Mais pourquoi donc le fait d'utiliser ios_base::good() ne garantirait pas
que
l'opération suivante soit réussie ? (De même, ios_base::fail() ne
garantirait-il pas que
l'opération suivante échoue ?)

Régis

"Michel Michaud" a écrit dans le message de news:
SpqLb.83898$
Dans news:btkri2$3g5$, Régis
Je te propose :

if( input ) {
while ( input.good() ) { // tt que eof non atteinte
ou pas d'erreur
input.get( Carac ); // lit 1 caractere
Taille++; // incr
}


Ça c'est à peu près certain de ne pas fonctionner. Il faut tester
après le get pour savoir si un caractère a été lu.

La technique de lecture en C++ (et en fait, c'est similaire en C)
a été montrée de nombreuses fois ici. Rappelons-la symboliquement :

while ( lecture ) // Combinaison de lecture et de test
{ // de la réussite
on a réussi à lire, on peut utiliser la donnée lue
}

Par exemple ici :

while (input.get(carac))
++taille;

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/




Avatar
Jean-Marc Bourguet
"Régis Troadec" writes:

C'est vrai et ta solution est plus commode.

Mais pourquoi donc le fait d'utiliser ios_base::good() ne
garantirait pas que l'opération suivante soit réussie ? (De même,
ios_base::fail() ne garantirait-il pas que l'opération suivante
échoue ?)


Parce que good() indique que l'operation precedente a reussit et
fail() qu'elle a echoue.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Thomas Abbé
donc

if( input ) {
while ( input.good() ) { // tt que eof non atteinte
input.get( Carac ); // lit 1 caractere
if (input)
Taille++; // incr
}

thomas
Avatar
kanze
Thomas Abbé wrote in message
news:<btkps4$9a7$...

oui et non.

FILE *f
fseek(f,0,SEEK_END);
int filesize = ftell(f);

et voila ;)


Sauf qu'en général, la taille d'un fichier ne tient pas sur un int. Si
le fseek est assez sûr, le ftell pourrait renvoyer n'importe quoi. Pour
déterminer la position dans un fichier, la fonction consacré par la
norme C, c'est fgetpos. Et la position est renvoyée dans un fpos_t, qui
n'est pas forcement un type numérique.

Même dans le cas des fichiers dont la taille tient sur un int, la norme
C spécifie « For a text stream, its file position indicator contains
unspecified information, usable by the fseek function for returning the
file position indicator for the stream to its position at the time of
the ftell call; the difference between two such return values is not
necessarily a meaninfgul measure of the number of characters written or
read. »

Si on veut déterminer la taille d'un fichier, il faut d'abord définir ce
qu'on veut dire par la taille. Si c'est la place que le fichier occupe
sur disque, ça serait une chose (et la valeur serait toujours un
multiple entier de la taille d'un bloc d'allocation). Si c'est le nombre
de char qu'on peut lire, la valeur serait d'autre chose, et sur la
plupart de systèmes non-Unix, au moins en ce qui concerne les fichiers
de texte, il n'y a aucune façon à la determiner *sauf* lire le fichier
complètement.

Mais le poster original ne disait pas qu'il voulait savoir la taille.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
kanze
"Laurent" wrote in message
news:<btk39j$l34$...

c'est simple, ce programme fonctionne normallement sans debug, et en
debug, il me trouve un eof() des le premier input.read()


Si le fichier ne contient qu'un seul caractère, c'est possible. Sinon,
je ne l'explique pas.

JE NE COMPRENDS PAS !!!!!!!!!!!

#include <iostream.h>
#include <fstream.h>
#include <stdio.h>

void main(void)


En général, la norme exige que main renvoie int, même si certains
compilateurs accepte void main.

{
ifstream input;
char Carac[1];
int Taille;

input.open("fichier.txt",ios::in);


C'est préférable de vérifier si le open a fonctionné ou non.

do
{
input.read(Carac, sizeof(Carac));
if(input.good())


Dans la pratique, ios::good() ne sert à rien. S'il renvoie faux, on sait
que la lecture prochaine échouera ; on ne sait toujours pas si la
dernière lecture a réussie ou non. S'il renvoie vrai, on sait que la
dernière lecture a réussie, mais on ne sait rien sur la prochaine.

{
Taille++;
}
}
while(!input.eof());


Ici aussi : ios::eof n'a d'intérêt qu'après un échec, et encore (parce
que c'est facile à construire des cas où il est vrai alors, bien que
l'échec soit dû à une erreur de formattage des données).

En général, le eofbit (que renvoie ios::eof, et qui entre dans les
conditions de good) est vrai si le flux a vu la fin de fichier
internalement, y compris s'il l'a vue lors d'un « look ahead ». Si le
bit est faux, tu ne peux pas dire grand chose (sauf qu'on n'a pas
terminé la dernière lecture à cause d'une fin de fichier). S'il est
vrai, tout ce qu'on peut dire de certain, c'est que la prochaine lecture
verait une fin de fichier (et donc échouerait).

La boucle idiomatique pour faire ce que tu fais ici, c'est :

while ( input.get( Charac[ 0 ] ) ) {
++ Taille ;
}

ou

while ( intput.get() != EOF ) {
++ Taille ;
}

Ce n'est pas beau, mais c'est tellement entré dans les moeurs que
quelque chose d'autre fait poser la question pourquoi. Si tu tiens à
utiliser des fonctions separées pour chaque opération :

input.get( Charac ) ;
while ( ! input.fail() ) {
++ Taille ;
input.get( Charac ) ;
}

Dans l'abstrait, c'est l'idiome que je préfère, mais comme j'ai dit,
c'est tellement peu courant que ça fait poser la question pourquoi. Le
fait d'utiliser quelque chose d'autre que l'idiome consacré dit au
lecteur que tu voulais faire quelque chose de spécial.

Les seuls cas où l'utilisation de ios::eof se justifie, c'est après des
lectures formattées, par exemple :

double d ;
while ( input >> d ) {
faisQuelqueChoseAvec( d ) ;
}
if ( ! input.eof() ) {
errorDeFormatEnEntree() ;
}

Là aussi, il s'agit d'un idiome consacré. Qui malheureusement ne marche
pas de façon robuste -- essaie par exemple sur un fichier qui contient
"1.2e+" (sans 'n' à la fin) : c'est bien une erreur de format qui a
provoquer l'arrêt de la lecture, mais sur toutes les implémentations que
je connais, on ne trouve pas d'erreur de format (et ces implémentations
sont bien conforme à la norme).

cout << "Taille : " << Taille << " octets.";
}


Et tu sors de ton programme avec une ligne incomplète ?

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

1 2 3