char* fgets

char* fgets - C - Programmation

Marsh Posté le 17-04-2010 à 13:26:33    

Bonjour a tous  :)  
 
Ce prototype de fonction retourne un pointeur, mais ou va être récupérer ce pointeur ? (car il n'y a pas d'affectation)
 

Code :
  1. char* fgets(char* chaine, int nombreDeCaracteresALire, FILE* pointeurSurFichier);
  2. fgets(chaine, TAILLE_MAX, fichier);


 
 
Ici on voit bien que ce prototype de fonction retourne un int et il sera affecté a la variable caractereActuel ce qui n'est pas le cas avec le 1er prototype..

Code :
  1. int fgetc(FILE* pointeurDeFichier);
  2. caractereActuel = fgetc(fichier);


Reply

Marsh Posté le 17-04-2010 à 13:26:33   

Reply

Marsh Posté le 17-04-2010 à 14:41:52    

Bon, dans ce qui suit, je vais supposer que chaine est un pointeur sur une zone mémoire de TAILLE_MAX caractères (alloué avec malloc). Il y a un deuxième cas de figure ou chaine est un tableau de TAILLE_MAX caractères, qui est équivalent, mais pour lequel il faudrait que je modifie certaines des formulations employées (parler de ce sur quoi pointe chaine si chaine est un pointeur, et parler du premier élément de chaine si chaine est un tableau, par exemple), et j'ai pas envie de retaper cela deux fois.
 
Dans le cas de fgets, quand tu fais
fgets(chaine, TAILLE_MAX, fichier);
ce que retourne fgets est un pointeur qui pointe sur la même zone que ce sur quoi pointe chaine.
 
A quoi ca sert?
Dans certains cas, ca sert a rien, alors on fait juste: fgets(chaine, TAILLE_MAX, fichier); et ensuite, on travaille avec chaine (dont le contenu de la zone pointée a été modifié par la fonction fgets).
 
Mais si je veux utiliser un pointeur pour parcourir la chaine de caractères, et mémoriser la début de la chaine de caractères, je vais faire:
char *chaine = malloc(TAILLE_MAX); // On alloue une zone de TAILLE_MAX caractères, chaine mémorise l'adresse de la zone allouée
char *mychaine;
fgets(chaine, TAILLE_MAX, fichier);
mychaine = chaine; // ils pointent maintenant sur la même zone
// utilisation
while (*mychaine++ != '\0') { ... } // utilisation de mychaine pour se déplacer dans la chaine de caractères
free (chaine); // on libère la zone mémoire, pour cela, chaine a conservé l'adresse de la zone allouée
 
 
J'aurais pu faire aussi  
char *chaine = malloc(TAILLE_MAX);
char *mychaine;
mychaine = chaine; // ils pointent maintenant sur la même zone
fgets(chaine, TAILLE_MAX, fichier);
etc
ça fait la même chose, mais les intentions sont un peut moins explicites
 
On peut encore faire:
char *chaine = malloc(TAILLE_MAX);
char *mychaine;
mychaine = fgets(chaine, TAILLE_MAX, fichier);
Si tout se passe bien avec fgets ça fait la même chose, mychaine et chaine pointeront sur la même zone.
Mais si ca se passe mal, chaine pointe toujours sur la même chose (la zone allouée), mais par contre, si fgets a échoué pour une certaine raison, mychaine vaudra NULL.
Donc déja, ca permet de tester si tout s'est bien passé: if (mychaine) {...} // Si fgets s'est bien passé
 
Il y a une technique équivalente, souvent utilisée:
char *chaine = malloc(TAILLE_MAX);
if (fgets(chaine, TAILLE_MAX, fichier)) {
    // si fgets a bien marché
    char *mychaine = chaine;
    // On bosse sur la chaine de caractères avec accès par pointeur: *mychaine
   // l'intérêt, c'est que quand on sort du bloc ici, mychaine a disparu
   // sa durée de vie a juste été le bloc ou en avait besoin
    .....
}
 
Quand on bosse avec un tableau, on peut utiliser des techniques similaires, mais bien souvent, plutôt que d'utiliser un pointeur pour bosser sur la chaine de caractères, on va utiliser un indice:
char chaine[TAILLE_MAX];
if (fgets(chaine, TAILLE_MAX, fichier)) {
    // si fgets a bien marché
    int i;
    for (i=0; i<TAILLE_MAX;i++) {
    // On bosse sur la chaine de caractères avec accès par indice: chaine[i]
    .....
    }
}
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 17-04-2010 à 15:51:10    

Je confirme en disant que l'on s'occupe rarement du pointeur renvoyé par fgets() si ce n'est, quelque fois, pour le comparer à null afin de voir s'il n'y a pas eu de problème.
 
En C, en principe, toutes les fonctions sont construites de manière interne pour que le registre AX, ou EAX, ou un couple de registres du CPU, reçoive la valeur qui est retournée. Comme il s'agit d'un registre, il n'est pas nécessaire de réserver de la place en mémoire pour cette valeur de retour, sauf si on veut la sauvegarder et s'en servir par la suite. Comme il s'agit d'un registre, cela explique aussi pourquoi les fonctions en C ne retournent jamais des tableaux, mais seulement des nombres ou des pointeurs.

Reply

Marsh Posté le 17-04-2010 à 18:21:38    

Merci..
 
Si j'ai bien compris j'envoie en 1er paramètre mon tableau de char , sa taille ex: 1000, et le pointeur sur FILE et la fonction retourne mon tableau de char rempli..
 
C'est ça?

Reply

Marsh Posté le 17-04-2010 à 18:30:33    

Exactement. Mais il n'est pas nécessairement totalement rempli, car la ligne lue peut faire moins de 1000 caractères.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 17-04-2010 à 19:28:27    

oui effectivement..
 
J'ai une autre question que je pose ici pour ne pas créer un autre sujet :
 

Citation :

fgets : lit une chaîne
fscanf : lit une chaîne formatée


 
 
Quel est la différence entre lire dans une chaîne et lire dans une chaîne formatée ?  

Reply

Marsh Posté le 17-04-2010 à 20:12:47    

fscanf a une indication du format de ce qu'il doit lire:
Exemple: fscanf(hf,"%15s %17s %127s\n", ip, mac, name);
Il y a une indication du format: "%15s %17s %127s\n"
On doit lire une ligne composée d'un premier champ d'au plus 15 caractères (autres que blancs, tab...), suivi d'au moins un blanc ou équivalent, suivi d'un autre champ d'au plus 17 caractères (autres que blancs, tab...), suivi d'au moins un blanc ou équivalent, suivi d'un autre champ d'au plus 127 caractères (autres que blancs, tab...), suivi de \n.
Si on ne lit pas cela, on aura une erreur, sinon, on range les valeurs dans les zones pointées par ip, mac et name.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 17-04-2010 à 20:22:05    

Merci gilou mais cela reste complexe ce qu'il y a ecrit dans fscanf(hf,"%15s %17s %127s\n", ip, mac, name); car je n'ai pas etudier cela
 
Pourrai-je avoir une explication simple de débutant ?

Reply

Marsh Posté le 17-04-2010 à 21:03:01    

Ben attends d'abord d'étudier cela, et on n'en reparlera.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed