Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2887 connectés 

  FORUM HardWare.fr
  Programmation

  [C++] Création de structures chainés à partir d'un fichier txt

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C++] Création de structures chainés à partir d'un fichier txt

n°120367
Moriaben
Posté le 02-04-2002 à 16:43:31  profilanswer
 

en gros j'ai un fichier stations.txt qui est de la forme suivante:
 
//Commentaires quelconques
1:station1:station2:station3
2:station1:station2
 
etc... vous aurez compris que "station1" c'est le nom d'une station de métro (avec divers caractères dont "-" , " " etc.)
 
en gros depuis ce fichier texte (il peut etre modifié, mais le format est tjrs le meme; il peut avoir 15 lignes, 20 lignes etc.. avec un nombre non fixé de stations par ligne), je veux créer une sructure chainé de ce format:
 
ligne 1 -> struct station1 -> struct station2 -> NULL
ligne 2 -> struct station1 -> struct station2 -> NULL
 
"MaillonSt" c'est une structure qui contient un tableau de 30 caractères TabSt( c'est pas un tableau dynamique), un entier NumSt (le numéro de la station sur la ligne; ex station1 -> NumSt == 1) et un pointeur vers la sructure MaillonSt (NULL si la ligne se termine)
"ligne" c'est un pointeur sur MaillonSt
 
j'aimerais pouvoir créer ça direct depuis le fichier txt (donc sans copier ligne par ligne ds un tableau)
 
J'ai déjà pas mal bossé dessus mais j'ai plusieurs problèmes, donc si vous pouviez m'aider svp :) notamment pour créer au début les pointeurs "ligne" , car qd on traite le fichier txt char par char, j'aurai un char ch=1 (1er char de la ligne) et si c'est la ligne 15 y'aura aussi un chiffre après etc..
bref c'est surtout la création des ptrs ligne qui me gène!
Merci d'avance !!

mood
Publicité
Posté le 02-04-2002 à 16:43:31  profilanswer
 

n°120452
youdontcar​e
Posté le 02-04-2002 à 18:13:45  profilanswer
 

si ton fichier tient en mémoire, tu peux le charger en entier et l'analyser d'un bloc.
 
pour lire des données, tu peux utiliser sscanf() & co. je n'en suis pas vraiment partisan et ça rame assez, donc le mieux est de se faire ses petites fonctions.
 
il te faut plusieurs choses :
* un moyen d'identifier une ligne (savoir où elle commence, où elle finit)
* dans cette ligne, identifier les caractères délimiteurs (seulement ':' dans ton cas)
* une fonction pour relire un entier, une autre pour relire une chaîne de caractères.
 
donc :
 
- tu lis le fichier : fopen(), fread(), etc dans un char* buffer.
 
- on définit deux indexs dans le buffer : int idx1 - début de la ligne. int idx2 - fin de la ligne.
 
- idx1 = 0;
 
- char* line = strstr(buffer, "\r\n" ) -> renvoie la position du retour à la ligne. idx2 = line - buffer donne la position de la fin de la ligne dans buffer. (la longueur de la ligne est donc idx2 - idx1.)
 
- il faut maintenant parser la ligne. format : un nombre, un ':', une station. puis peut se trouver une suite de ':' + station.
 
- on utilise un nouvel index, int curIdx = idx1 qui va servir à se repérer dans la ligne.
 
- pour chopper l'entier, on lit la chaine tant qu'il y a des chiffres, on update curIdx.
 
int parseNumber(char* buffer, int* curIdx)
{
  int n = 0;
  // tant qu'il y a des chiffres ...
  while (*buffer >= '0' && *buffer <= '9';)
  {
    n = n*10;
    n += *buffer - '0';
    *curIdx++;
    *buffer++;
  }
  return n;
}
 
on l'appelle avec parseNumber(&buffer[idx1], &curIdx). (on lui passe le début de la ligne, on update l'index).
 
- curIdx pointe maintenant sur ':'. ça peut servir de test de format de ton fichier :
 
if (buffer[curIdx] != ':';) maFonctionDerreur('format invalide ...';);
 
on incrémente curIdx pour passer le ':'.  
 
curIdx++;
 
- maintenant, on parse le premier nom de station :
 
int parseString(char* buffer, int* curIdx, char* dest)
{
   int len = 0;
   // tant qu'on a un caractère différent de ':', on le range dans le tableau
   while (*buffer != ':';)
   {
     dest[len] = *buffer;
     *curIdx++;
     *buffer++;
     len++;      
   }
   // zéro terminateur
   dest[len] = 0;
   return len;
}
 
il ne te suffit de l'appeler avec
 
MaillonSt curLine;
 
parseString(&buffer[curIdx], &curIdx, &curLine->NomDeLaStation[0]);
 
- maintenant, c'est simple : tu as obligatoirement (si ton fichier est bien formé) un ':' et un nom.
 
while (buffer[curIdx] == ':';)
{
  curIdx++;
  parseString(... comme au-dessus).
}
 
- dès que buffer[curIdx] est différent de ':', c'est la fin de la ligne. on a l'index de fin de ligne : idx2. une nouvelle ligne (sous windows tout du moins) c'est deux caractères, \r\n, il suffit de rajouter 2 à idx2 pour avoir la nouvelle ligne :
 
curidx1 = curidx2 + 2;
 
on cherche alors la fin de la ligne :
 
curidx2 = strstr(&buffer[curidx1], strstr) - buffer;
 
et hop.
 
//  
 
il manque certains trucs, comme la vérification que parseString() ne parse pas une string de + de 30 caractères, etc. les procédures parseX peuvent être améliorés, (ne garder qu'un index, etc.)

n°120521
Moriaben
Posté le 02-04-2002 à 21:51:47  profilanswer
 

oulah on a pas fait tant de trucs nous :)
enfait jconnais que le systeme de copiage caractère par caractère du type: while ( from.get(ch) ) to.put(ch);

n°120526
Goratrix
Posté le 02-04-2002 à 22:07:50  profilanswer
 

Moriaben a écrit a écrit :

oulah on a pas fait tant de trucs nous :)
enfait jconnais que le systeme de copiage caractère par caractère du type: while ( from.get(ch) ) to.put(ch);  




 
mouhahah :D  :D  
fo reconnaitre que tout ce code C ca balancé d'un coup ca peut faire peur si on est pas trop habitué...
 
mais fo reconnaitre que youdontcare a généralement des explications assez terribles...si on arrive a tout suivre.. ;)


---------------
"The oldest and strongest emotion of Mankind is Fear and the oldest and strongest Fear is the Fear of the Unknown"
n°120529
Moriaben
Posté le 02-04-2002 à 22:09:33  profilanswer
 

moi je largue assez rapidement enfait :p

n°120562
youdontcar​e
Posté le 02-04-2002 à 22:49:00  profilanswer
 

précise que tu débutes, j'aurais essayé encore plus détaillé ;)
 
pour le code, je t'ai filé les étapes, les fonctions à utiliser. pour celles comme fseek() & co, tu regardes l'aide, pour les autre, tu les tapes et tu les débuggues, tu comprendras bien plus vite plutôt que de regarder du code sur une page html.

n°120585
Moriaben
Posté le 02-04-2002 à 23:31:37  profilanswer
 

utiliser toutes ces fonctions ...
ah oui j'ai oublié de dire que je peux lire qu'une seule fois le fichier :)
 
enfait je pensais plutot utiliser des if, des while, etc pas des fonctions super compliquées :)

n°120587
youdontcar​e
Posté le 02-04-2002 à 23:37:14  profilanswer
 

pour toi des fonctions de dix lignes sont compliquées ? :)
 
enfin, ce qui compte, c'est la pratique, donc va pratiquer et reviens si t'es bloqué.

n°120597
Moriaben
Posté le 03-04-2002 à 00:05:32  profilanswer
 

moi enfait il me faudrait plus un truc de ce style:
 
do
  {
   from.get(ch);
   if ( from.good() )  to.put(ch);
  }  
while ( from.good() );

n°120606
Moriaben
Posté le 03-04-2002 à 00:15:57  profilanswer
 

j'aimerais savoir un truc
ds mon dernier exemple, le buffer s'appelle from et j'utilise une boucle qui lit char par char (du fichier txt)
si je quitte la boucle et que j'en commence une autre (tjrs avec from) est-ce que from recommencera la lecture au début du fichier txt ou à l'endroit où il s'est arreté avec la 1ere boucle ?


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation

  [C++] Création de structures chainés à partir d'un fichier txt

 

Sujets relatifs
Access et création de fichier[VB] explorateur de fichier
creation d'un site portail HELP![VB] envoie d'un fichier
[Premier pas en delphi] InputQuery ??? , Creation d'un menu???Afficher une ligne precise ds un fichier texte???????
[Editeur] Editeur qui rafraichit un fichier auto.[C++ Builder] Socket : envoyer des structures
creation d'un .reg pour modifer la base 
Plus de sujets relatifs à : [C++] Création de structures chainés à partir d'un fichier txt


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR