Lire une chaîne de caractères de taille variable sur stdin
2 participants
Page 1 sur 1
Lire une chaîne de caractères de taille variable sur stdin
Bonjour tout le monde,
Tout à coup j'ai eu une subite envie de faire une petite fonction permettant de lire une chaînes de caractères de taille variable sur stdin (et plus généralement, sur un FILE *).
Le comportement de la fonction est le suivant :
- La fonction prend un paramètre, le flux (FILE *) sur lequel la chaîne de caractères sera lue
- La fonction retournera un char *, l'adresse du premier caractère lu ou NULL si une erreur survient
- Si une erreur survient, le flux sera consommé (= lecture des caractères juqu'à ce qu'on tombe sur \n ou EOF)
La signature de la fonction sera donc la suivante : char * get_line(FILE *);
N'ayant pas trouvé grand chose sur la lecture de chaînes de caractères de taille variable, j'ai du faire chauffer mes méninges et trouver un algorithme, espèrons qu'il soit potable.
Ne sachant pas trop comment écrire cela en pseudo-code, je vais le faire avec de bonnes vieilles phrases.
Première question, est-ce que cet algorithme semble correct, potable ?
Pour la réallocation, j'ai vu certains codes qui doublaient la taille de l'espace alloué au lieu de l'agrandir d'un nombre fixe d'octets. Y a-t-il une méthode préférable à l'autre, ou est-ce dépendant de la situation ? Et si c'est dépendant de la situation, quelle méthode répondrait le mieux à la problématique actuelle ?
Passons maintenant à l'implémentation en C :
Qu'en pensez-vous ?
Le code semble fonctionner. Semble car j'avoue avoir un peu de mal pour les tests unitaires.. Est-il possible de faire échouer volontairement un malloc/realloc ?
Dernière petite chose, j'ai eu beau lutter, un warning persiste à la compilation.. J'utilise code::block avec les options de compilations suivantes (GNU/CSS compiler) : -Wall -Wextra -ansi -O -Wwrite-strings -Wstrict-prototypes -Wuninitialized -Wunreachable-code
Et voici le warning en question :
J'ai demandé à une connaissance de compiler, il a utilisé le même compilateur (mais je ne sais pas si c'est la même version par contre) avec les mêmes options, et point de warning chez lui.
Merci d'avoir pris le temps de me lire et merci d'avance pour vos futures réponses. :)
Cordialement, Krystal.
Tout à coup j'ai eu une subite envie de faire une petite fonction permettant de lire une chaînes de caractères de taille variable sur stdin (et plus généralement, sur un FILE *).
Le comportement de la fonction est le suivant :
- La fonction prend un paramètre, le flux (FILE *) sur lequel la chaîne de caractères sera lue
- La fonction retournera un char *, l'adresse du premier caractère lu ou NULL si une erreur survient
- Si une erreur survient, le flux sera consommé (= lecture des caractères juqu'à ce qu'on tombe sur \n ou EOF)
La signature de la fonction sera donc la suivante : char * get_line(FILE *);
N'ayant pas trouvé grand chose sur la lecture de chaînes de caractères de taille variable, j'ai du faire chauffer mes méninges et trouver un algorithme, espèrons qu'il soit potable.
Ne sachant pas trop comment écrire cela en pseudo-code, je vais le faire avec de bonnes vieilles phrases.
- Code:
D'abord on va allouer un espace mémoire de taille arbitraire (32 octets) pouvant stocker des char.
Si l'allocation a réussie, on va pouvoir lire le flux caractère par caractère.
Tant qu'on ne rencontre pas \n ou EOF :
Si l'espace alloué n'est pas suffisant, on va augmenter la taille de l'espace précédemment alloué (+ 32 octets).
Si l'allocation a échouée, on va libérer l'espace précédemment alloué, consommer le flux et sortir de la boucle.
S'il n'y a pas eu d'erreur d'allocation, on rajoute le \0 à la chaîne de caractères.
On retourne un pointeur sur le premier élément de l'espace alloué ou NULL s'il y a eu une erreur d'allocation.
Première question, est-ce que cet algorithme semble correct, potable ?
Pour la réallocation, j'ai vu certains codes qui doublaient la taille de l'espace alloué au lieu de l'agrandir d'un nombre fixe d'octets. Y a-t-il une méthode préférable à l'autre, ou est-ce dépendant de la situation ? Et si c'est dépendant de la situation, quelle méthode répondrait le mieux à la problématique actuelle ?
Passons maintenant à l'implémentation en C :
- Code:
/* /Document/C/str/mstr.h */
#ifndef MSTR_H_INCLUDED
#define MSTR_H_INCLUDED
#include <stdlib.h>
#include <stdio.h>
#define MSTR_ALLOC_BLOCK_SIZE 32
char * get_line(FILE *);
#endif /* MSTR_H_INCLUDED */
- Code:
/* /Document/C/str/mstr.c */
#include "mstr.h"
char * get_line(FILE * stream) {
/* Allocation du bloc de depart */
size_t size = MSTR_ALLOC_BLOCK_SIZE;
char * s = malloc(size);
/* Si l'allocation a reussie */
if(s != NULL) {
size_t i;
int c;
/* On lit tous les caractères jusqu'a \n ou EOF */
for(i = 0; (c = fgetc(stream)) != '\n' && c != EOF; i++) {
/* Si l'espace alloue n'est plus suffisant
on essaie de l'agrandir */
if(i >= size) {
char * tmp = realloc(s, size += MSTR_ALLOC_BLOCK_SIZE);
/* Si l'allocation a reussie, on recupere le pointeur
Sinon on libere l'espace precedemment alloue,
on vide le buffer du flux et on sort du while */
if(tmp != NULL) {
s = tmp;
}
else {
free(s);
s = NULL;
while((c = fgetc(stream)) != '\n' && c != EOF) {
}
break;
}
}
s[i] = (char)c;
}
/* On ajoute le \0 terminal a la chaine recuperee */
if(s != NULL) {
s[i] = '\0';
}
}
return s;
}
Qu'en pensez-vous ?
Le code semble fonctionner. Semble car j'avoue avoir un peu de mal pour les tests unitaires.. Est-il possible de faire échouer volontairement un malloc/realloc ?
Dernière petite chose, j'ai eu beau lutter, un warning persiste à la compilation.. J'utilise code::block avec les options de compilations suivantes (GNU/CSS compiler) : -Wall -Wextra -ansi -O -Wwrite-strings -Wstrict-prototypes -Wuninitialized -Wunreachable-code
Et voici le warning en question :
- Code:
\Documents\C\str\mstr.c||In function `get_line':|
\Documents\C\str\mstr.c|10|warning: will never be executed|
||=== Build finished: 0 errors, 1 warnings ===|
J'ai demandé à une connaissance de compiler, il a utilisé le même compilateur (mais je ne sais pas si c'est la même version par contre) avec les mêmes options, et point de warning chez lui.
Merci d'avoir pris le temps de me lire et merci d'avance pour vos futures réponses. :)
Cordialement, Krystal.
Krystal- Messages : 2
Date d'inscription : 23/09/2008
Re: Lire une chaîne de caractères de taille variable sur stdin
Bonjour,
Je t'ai répondu sur DVP.
A+
Emmanuel
Je t'ai répondu sur DVP.
A+
Emmanuel
Re: Lire une chaîne de caractères de taille variable sur stdin
Merci beaucoup.
Voici le lien du fil sur developpez pour ceux qui seraient intéressés : http://www.developpez.net/forums/d617984/c-cpp/c/lire-chaine-caracteres-taille-variable-stdin/
Bonne soirée.
Voici le lien du fil sur developpez pour ceux qui seraient intéressés : http://www.developpez.net/forums/d617984/c-cpp/c/lire-chaine-caracteres-taille-variable-stdin/
Bonne soirée.
Krystal- Messages : 2
Date d'inscription : 23/09/2008
Re: Lire une chaîne de caractères de taille variable sur stdin
Oui, il suffisait de clicker sur ma réponse !Krystal a écrit:Voici le lien du fil sur developpez pour ceux qui seraient intéressés : http://www.developpez.net/forums/d617984/c-cpp/c/lire-chaine-caracteres-taille-variable-stdin/
Sujets similaires
» Lire un texte de taille inconnue a partir de la STDIN
» Affichage liste chaine C90
» comparaison de deux chaines de caracteres
» Affichage liste chaine C90
» comparaison de deux chaines de caracteres
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum
|
|