récuperer un caractère dans un fichier avec read - C - Programmation
Marsh Posté le 24-11-2012 à 18:39:18
Bonjour !
Vous ouvrez le fichier en mode "write only" (O_WRONLY), en demandant au système de le créer si nécessaire, ce qui n'est pas des plus astucieux pour lire le contenu du fichier !
Vous devriez tenter :
int f = open("ff", O_RDONLY);
Puis tester (éventuellement dans la fonction "read_line" qui pourrait dans ce cas-là renvoyer NULL), que f n'est pas égal à -1 (que le fichier a donc bien été ouvert).
Par ailleurs, votre gestion de la mémoire comporte plusieurs erreurs :
* ligne 6 : line = (char *) malloc (sizeof(char)); [Note : la norme impose sizeof(char) = 1, donc on peut ne pas le préciser, mais ce n'est pas une faute de le mettre], car vous voulez stocker dans line 1 caractère, pas un pointeur sur un caractère.
* ligne 16 : line = (char *)realloc(line, (1+i)*sizeof(char));
* Au vu des faibles tailles de mémoire qui sont demandées, les fonctions malloc et realloc se déroulement correctement, mais, en théorie, vous devriez tester qu'elles ne renvoient pas NULL, ce qui indiquerait que la mémoire demandée ne peut être allouée.
De plus, vous ne vérifiez pas que la fonction read se déroule correctement (code de retour = nombre d'octets lus, soit 1 dans le cas présent).
Pour terminer, n'oubliez pas de libérer la mémoire allouée par la fonction "read_line"
Bonne continuation à vous !
Marsh Posté le 24-11-2012 à 18:49:38
Farian a écrit : Bonjour ! |
Merci pour votre réponse, par contre, à l’exécution :
Code :
|
n'affiche pas le bon caractère qui est sensé se trouver dans mon fichier mais un autre
et puis juste après l'avoir affiché, l’exécution plante même après vos modifications
Marsh Posté le 24-11-2012 à 18:54:38
Re-bonjour !
Comme je le dis souvent : "CMCM" ! (Chez Moi, Ça Marche ), et valgrind ne trouve rien à redire lors de l'exécution ...
Il doit y avoir une autre petite erreur dans votre code, postez-le, cela ne doit pas être grand chose.
Marsh Posté le 24-11-2012 à 19:00:51
Je suis trop bête !!!!! j'avais oublié de mettre mon fichier dans le même dossier que mon main ^^
problème résolu merci encore
Marsh Posté le 24-11-2012 à 19:15:21
Je ne vois pas de faute, si ce n'est que j'aurais remplacé le code "if (errno)" par "if (f < 0)", qui est quand même plus propre, mais qui doit revenir au même ...
Chez moi, votre code s'exécute sans problème (valgrind ok)
Que ce soit sous windows ne devrait, en théorie, pas poser de problème ... la seule chose que je vois est que si votre fichier ne contient qu'une seule ligne et donc pas de retour chariot, le comportement sera sans doute étrange ...)
Ma version du code, qui ajoute simplement la gestion du code de retour de la fonction "read" :
Code :
|
Marsh Posté le 24-11-2012 à 19:16:06
Hé hé ! J'étais trop occupé à mettre en forme ma version du code et j'avais raté votre dernier message
Tout est bien qui finit bien, donc !
Bonne continuation à vous !
Marsh Posté le 25-11-2012 à 00:32:34
j'ai toujours un problème j'arrive bien à récupérer ma ligne, mais après mon return line; je récupère NULL je comprends pas...
Marsh Posté le 25-11-2012 à 09:19:22
Précisez votre problème ...
Le code que j'ai posté, moyennant quelques petites adaptations, cf. ci-dessous, fonctionne correctement, pour plusieurs lignes :
Code :
|
Marsh Posté le 25-11-2012 à 12:10:01
je viens de reregarder mon code et j'avais oublié de faire un free, maintenant ça marche ( pour de bon cette fois ^^ )
merci encore
Marsh Posté le 25-11-2012 à 12:38:32
Farian a écrit : Le code que j'ai posté, moyennant quelques petites adaptations, cf. ci-dessous, fonctionne correctement, pour plusieurs lignes |
Bonjour
Oui il fonctionne. Mais faire des realloc de 1 en 1 c'est pas super super optimisé vitesse. De plus, mettre le mode 0644 dans open() ne se justifie que si le fichier est créé donc si on passe le flag "O_CREATE" (ce qui s'adapte mal avec le flag O_RDONLY)
Et tant qu'à mettre un mode, autant utiliser les constantes appropriées S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH...
Marsh Posté le 25-11-2012 à 17:55:23
Sve@r a écrit : |
Pour le realloc de 1 en 1 c'est ce qui m'est demandé : ça permet de pas avoir de problèmes si la chaine dépasse le buffer et aussi de pas gaspiller de l'espace pour rien.
Marsh Posté le 25-11-2012 à 22:35:30
Benh_31 a écrit : Pour le realloc de 1 en 1 c'est ce qui m'est demandé : ça permet de pas avoir de problèmes si la chaine dépasse le buffer et aussi de pas gaspiller de l'espace pour rien. |
Il est bien évident qu'il faut réallouer pour éviter un dépassement. Mais de 1 en 1...
En fait, le gaspillage d'espace est bien évidemment un problème à prendre en compte mais c'est là qu'on peut faire des compromis entre ce problème et les autres. Par exemple allouer de 100 en 100 permettra une certaine souplesse (surtout qu'on lit une ligne et que les lignes de plus de 100 caractères ne sont pas courantes) et le gaspillage n'est pas énorme.
Bien entendu s'il est demandé spécifiquement une allocation de 1 en 1 tu le fais mais rien ne t'empêche d'aller au-delà de ce qui est demandé. Par exemple la taille d'allocation pourrait être une macro ce qui permettrait à ton code d'évoluer facilement si besoin était. C'est ce qu'on nomme "évolutivité"...
Marsh Posté le 26-11-2012 à 19:07:36
c'est sur je suis tout à fait d'accord avec toi, dans mon cas c'est ce qui m'est demandé
Marsh Posté le 26-11-2012 à 22:50:37
Farian a écrit : Précisez votre problème ... Le code que j'ai posté, moyennant quelques petites adaptations, cf. ci-dessous, fonctionne correctement, pour plusieurs lignes : |
Il marche, mais il n'est néanmoins pas parfait: c'est malloc(sizeof(char)) que l'on devrait avoir, et non malloc(sizeof(char*)) et idem pour le réalloc.
A+,
Marsh Posté le 24-11-2012 à 18:16:40
Bonjour à tous,
alors voila j'ai fais une fonction permettant de renvoyer la première ligne d'un fichier.
Le problème c'est que dès la ligne 10, quand j'essaie d'afficher le caractère lu dans la variable courant, ben ça marche pas ^^
quelqu'un saurait m'expliquer ?
avec son main :
le fichier ff contient bien des caractères, des retours à la ligne...
merci d'avance