Lire un fichier en c++ [Résolu]

Signaler
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007
-
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
-
bonjour,
en fait pour lire dans un fichier  j'utilise la boucle suivante:

vector <string> Vector;
while (!fichierEnvoye.eof())
      {
       fichierEnvoye.read(Paquet,1400);
       Vector.push_back(Paquet);           //on stocke chaque ligne du fichier lu dans un tbl de vector
          vider(Paquet);
      }

la lecture marche tres bien avec les fichier.txt, mais une fois j'essaye d'ouvrir des fichier.doc ou .pdf ou autres, ça bloque dans la 1ere iteration
auriez vous une idee de ce qui cloche dans cette boucle ? peut etre l'utilisation des string ou la classe vector ??

34 réponses

Messages postés
565
Date d'inscription
mercredi 19 mai 2004
Statut
Membre
Dernière intervention
30 avril 2008
1
Salut.
Il te faut lire en mode binary.
Dans ton cas en it / bit. donc des paquet le splus petit possible(la taille d'un carractere). enssuite, tu li ce paquet, si il est egal a NULL , tu lis le suivant , et ceci jusqua une limite que tu as fixé(tu peu fixé cette limite en fonction de la taille du fichier).Si en chemin tu tombe sur un carractere diferent de null , du remet le compteur a zero.Si toutefois il ny a que des null jusqua cette limite c'est que tu a atteint la fin du fichier.
Dsl de ne pas pouvoir taider davantage mais je suis plutot axé Vb.
Sinon recherche sur le forum "Lire fichier bianaire" ou "for binary"...au pire msdn.
Voila onne chance

Si l'informatique été de l'alcool il y aurait des genies partout
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
6
Bonjour,

Essaye non pas de récupérer via un string mais avec une chaîne de caractère :

char buffer[4096];

nombre_de_caractere=recv(id_de_la_socket,buffer,4096,0);

if (nombre_de_caractere==SOCKET_ERROR)

      printf("\nDesole, je n'ai pas recu de donnee");

else
{
    //
nombre_de_caractere est le nombre de caractère reçu
    // Attention ! C'est cette variable qui indique le nombre de caractère à écrire et non pas strlen()
    // Je conseille donc d'écrire manuellement par boucle for caractère par caractère
}
Un autre truc c'est juste le code de réception mais il faut que tu vérifie si
nombre_de_caractere correspond à ce que tu devais reçevoir dans un for afin de continuer de reçevoir la suite

Sinon je te conseille un site pour les sockets connectés : http://www.frameip.com/c-mode-connecte/

PS : Si ta question originale est résolue tu peux cliquer sur 'Réponse acceptée' pour ceux qui t'ont aidé.

Merci et bonne prog,
@++

Le créateur du site http://victorlogiciels.com
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007

ben merci,
j'ai fait la lecture en mode binaire, ça regle en partie le probleme, maintenant j'arrive au moins a lire tout le fichier.
sauf que le fichier je le lis pr l'envoyer ensuite a un distinataire, mais ya des caracteres qui sont pas bien afficher qd j'ouvre le fichier reçu.
peut etre que je dois changer qlq chose dans la fonction qui ecrit les paquets reçus dans le code du recepteur ?
Messages postés
565
Date d'inscription
mercredi 19 mai 2004
Statut
Membre
Dernière intervention
30 avril 2008
1
surement la norme ISO qui doit diferéré dune fonction a lautre :/
Desolé mais je ne suis pas qualifié pour taider
Cependant dautre on deja eut ce pb... une recherche approfondie pourra peutetre taider.
Au pire post un autre message sur le forum , avec ton code.
Et si ma premiere reponse te convient , check "Reponse acceptée "

Si l'informatique été de l'alcool il y aurait des genies partout
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
6
Bonjour,

Tu utilise quel fonction pour l'envoi et la réception.

Nous montrer le code qui envoi et qui reçoit serait bien venu pour te conseiller.

Merci et bonne prog,
@++

Le créateur du site http://victorlogiciels.com
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007

ok, voici le code pour l'envoi:

string buffer;
 for(int i=0;i<T.size();)
    {
     buffer.erase(0,buffer.size());
     itoa(i,p,10);
     buffer=p;
     buffer+='-';
     buffer+=T[i];
     nResult=sendto(sockfd,buffer.c_str(),buffer.size(),0,(sockaddr *)&serveur_addr,serveur_addrLen );
}
 
et voici le code pour la reception

  for(int k=0;k<end;k++)
  {
  for(int i=0;i<1420;i++) Buffer[i]=0;
  recvfrom(sock,Buffer,sizeof(Buffer),0,(sockaddr *)&client_addr,&client_addrLen);
 fichierRecu.write(Buffer,1400);
 }

j'utilise les string pcq j'ai besoin d'inserer des entetes dans chaque paquets pr identifier les duplica pcq j'utilise UDP et je dois m'assurer de la bonne reception des paquets.
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007

j'ai oublié de préciser que j'envoi la taille de fichier au debut, pr que le recepteur sache qd est ce que il faut s'arreter de recevoir, et la variable end = taille/1400 +1
pcq chaque paquet que j'envoi contient 1400octet de donnees
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007

la en fait je viens de découvrir un autre probleme dans mon code et j'aimerai bien que vous m'aidiez la dessus.
en fait pour utiliser le mode UDP avec fiabilité, j'exige du recepteur de m'envoyer des ACK a chaque fois qu'il reçoit un paquet, et pour cela j'utilise des timeout sur recvfrom à l'aide de la fonction select( ) pr qu'elle ne bloque pas ou cas ou je ne reçois pas les ACK.
qd j'essaye d'envoyer des fichier de petite taille (qlq Mo) ça marche bien, mais une fois j'essaye d'envoyer des fichier de l'ordre de 40 Mo, la fonction recvfrom n'attend plus l'expiration du delai et m'envoyer toute suite une erreur de reception.
voici le code, seulement la partie ou j'envoi les information sur le fichier au destinataire:

    timeval TimeOut;         //Timeout pour la reception des acquiescements
    TimeOut.tv_sec=5;
    TimeOut.tv_usec=0;

 char p[1];
 itoa(size,p,10);                //conversion int to char
 string info(UpLoadFile);
 string taille=p;
 info+="-";
 info+=taille;
 info+="-";                      //fanion

 fd_set ensemble; 
 
nResult=sendto(sockfd,buf,info.size(),0,(sockaddr *)&serveur_addr,serveur_addrLen );
 if(nResult<0) cout<<"Erreur d'envoie"<<endl;



 FD_ZERO(&ensemble);
 FD_SET(sockfd,&ensemble);
 
 int retval=select(0, &ensemble, 0, 0, &TimeOut);
 if(retval) {
    recvfrom(sockfd,AckBuf,sizeof(AckBuf), 0,(sockaddr *)&serveur_addr,&serveur_addrLen );  // Recéption des données en provenances du destinataire
 cout<<"L'echange peut etre etabli maintenant! "<<AckBuf<<endl;
 }
 if(retval==0) cout<<"erreur de reception ACK"<<endl;



donc la quand j'essaye d'envoyer un grand fichier, il m'affiche tout de suite "erreur de reception ACK" sans attendre les 5secondes du timeout.
je ne comprend vraiment rien !
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007

l'erreur que j'ai commise, c'etait l'utilisation de p[1] avec itoa pr faire la conversion,
j'aurais du utilisé un tableau plus grand p[10] par exemple, c etait ça qui emepchait select( ) de faire un timeout qd le nombre a convertir devient tres grand.
a propos de ta proposition d'utiliser des char au lieu des string, j'ai pensé à ça aussi mais comme tu px le remarquer, je dois traiter le paquet avant de l'envoyer, ajouter numero de sequence et des trucs de ce genre, et les string me facilitent vraiment la tache, mais si c'est la seule solution qui se presente, je serai alors obligé d'utiliser des char.
en tout cas merci pr votre aide, et si vous avez d'autres propositions, je suis a l'ecoute.
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007

j'ai essayé comme t'as dit de copie ça dans un char, mais ça marche tjrs pas!!!!
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
6
Bonjour,

Allez je t'ai fait une source : http://www.cppfrance.com/code.aspx?ID=41921
Merci et bonne prog,
@++

Le créateur du site http://victorlogiciels.com
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007

oh merci man, c vraiment tres gentil de ta part :)
j'aurai une question a propos de la façon dont tu ouvres les fichier, dans ton code tu utilises ça:
ifstream fichiero(adr_fic,ios::in|ios::binary);
 ofstream fichiers(nomdefichier,ios::out|ios::binary);

tandis que moi, je fais comme ça:

fichierEnvoye.open(UpLoadFile,ios::binary);
fichierRecu.open(DownLoadFile,ios::binary);

serait il pas à cause de ça que j'arrive pas envoyer correctement des fichier .doc ou .pdf  ?

et merci encore pr ton aide
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
6
Bonjour,

Le code équivalent au mien est celui-ci :

ifstream fichiero;
 fichiero.open(adr_fic,ios::in|ios::binary);

ofstream fichiers;

fichiers.open(nomdefichier,ios::out|ios::binary);
Merci et bonne prog,
@++

Le créateur du site http://victorlogiciels.com
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
6
Bonjour,

Sinon pour tester ta fonction d'écriture/lecture tu fais un copieur de fichier sans utiliser le réseau (qui duplique le fichier) si le fichier passe c'est que c'est au niveau des sockets sinon c'est que c'est soit la fonction de lecture, soit d'écriture soit les 2.

Si j'ai pas été assez clair dans mon explication tu le dis.

Je reformule, en gros : - Tu copies ton code de lecture dans un nouveau programme
- Tu colles à la suite selui d'écriture (qui va enregistrer le fichier de destination avec un nom différent de celui de lecture)
- Tu vérifies que ça fonctionne et conclus

Merci et bonne prog,
@++

Le créateur du site http://victorlogiciels.com
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007

ok je vais essayer de faire ca, merci pour l'aide
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
6
Bonjour,

De rien mais n'oublie pas de noter et de laisser un p'tit commentaire sur la source

Merci et bonne prog,
@++

Le créateur du site http://victorlogiciels.com
Messages postés
49
Date d'inscription
mardi 14 février 2006
Statut
Membre
Dernière intervention
27 novembre 2007

toujours le meme probleme avec les .doc
je vais montrer mon code de lecture et d'envoi du fichier, puis le code de reception:

/*******************   fonction de lecture  *****************************/

void LireFichier(char UpLoadFile[20],char** Buffer)
{
  ifstream fichierEnvoye;
  


  fichierEnvoye.open(UpLoadFile,ios::in|ios::binary);
  if(fichierEnvoye.fail())
    {
     cout << "Erreur lors de l'ouverture du fichier." << endl;
     system("PAUSE");
      return;
    }
  else
  {
   int t=0;
   while (!fichierEnvoye.eof())
      {
       fichierEnvoye.read(*(Buffer+t),1400);
       t++;
      
      }
  }
 
  fichierEnvoye.close();
}

/****************************************************************************/

/********************************* code d'envoi *****************************/
int dim=size/1400+1;                 //size est la taille du fichier

char** Buffer=new char*[dim];
LireFichier(UpLoadFile,Buffer);   //UpLoadFile contient le nom du fichier

for(int i=0;i<dim;)                      // Nombre d'iteration = nombre de paquet a envoyer
    {  
     buffer.erase(0,buffer.size());                     // On vide buffer
     itoa(i,p,10);
     buffer=p;                          // Construction de l'entete du paquet avec le numero de sequence
     buffer+='-';
     for(int f=0;f<buffer.size();f++) Paquet[f]=buffer[f];            // On copie l'entete dans le paquet a envoyer
     for(int g=0;g<1400;g++)
     {
      Paquet[f]=Buffer[i][g];                   // Copie les donnees dans le paquet
      f++;
     }
     nResult=sendto(sockfd,Paquet,BF_SIZE,0,(sockaddr *)&serveur_addr,serveur_addrLen );  // Envoi des paquets
}

/************************** code de  reception *******************************************/



fichierRecu.open(DownLoadFile,ios::out|ios::binary);




int end=(1+FileSize/1400);




int m;




cout<<"Paquets recus :"<<endl;




for(int k=0;k<end;)




{




memset(Buffer,0,1420);




nResult=recvfrom(sock,Buffer,sizeof(Buffer),0,(sockaddr *)&client_addr,&client_addrLen);




m=0;




while(Buffer[m]!='-')                         //on extrait le numero de sequence




{




Seq[m]=Buffer[m];




m++;




}










for(int n=m+1;n<nResult;n++)                  //puis on decale pour ne plus ecrire le numero de sequence dans le fichier




{




Buffer[n-m-1]=Buffer[n];




}




SeqNum=atoi(Seq);                                              //conversion char to int


memset(Seq,0,10);


if(SeqNum==k)                 //si le paquet correspond a celui attendu


{


itoa(SeqNum,AckBuf,10);


sendto(sock,AckBuf,sizeof(AckBuf),0,(sockaddr *)&client_addr,client_addrLen);    //on envoit l'ACK


fichierRecu.write(Buffer,nResult);                                                                                     //et on ecrit dans le fichier


cout<<SeqNum<<":"<<k<<"-";


k++;


}








 
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
6
Bonjour,

C'est quoi ce char** ?
char** Buffer=new char*[dim];

Merci et bonne prog,
@++

Le créateur du site http://victorlogiciels.com
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
6
Bonjour,

Je comprends pas ce que ton programme veut faire avec ta séquence "-".

Merci et bonne prog,
@++

Le créateur du site http://victorlogiciels.com
Messages postés
1100
Date d'inscription
jeudi 24 avril 2003
Statut
Membre
Dernière intervention
17 octobre 2012
6
Bonjour,

Cette ligne de code est incompréhensible : Buffer est un char** et t un entier et tu les mélanges en les additionnants (ce que tu additionne c'est son adresse avec t).
Je te la met mais barré car je peux pas montrer ça.
<strike>fichierEnvoye.read(*(Buffer+t),1400);
</strike>
Merci et bonne prog,
@++

Le créateur du site http://victorlogiciels.com