OVH Cloud OVH Cloud

fwrite qui plante

4 réponses
Avatar
Nicolas Favre-Félix
Bonjour.

J'ai un problème vraiment incompréhensible lors de l'écriture d'un fichier.
Voici le code:


buffer = (char*)malloc(200 * sizeof(char)); // on alloue bien assez
sprintf(buffer, "%d\n%d\n%d\n", nb_t, nb_v, nb_s);/
printf("buffer='%s', taille=%d\n", buffer, strlen(buffer));

f = fopen(fichier, "w");// ouverture en écriture
fseek(f, 0, SEEK_SET); // pointe sur le début
printf("derniere ligne avant ecriture...\n");
fwrite(buffer, sizeof(char),strlen(buffer), f); / plante!


la chaine buffer est créée, puis j'y mets 3 nombres.
j'ai en sortie :

buffer='104
1000
2000
', taille=14

Pile ce que je veux écrire bans le fichier.
Je vois s'afficher derniere ligne avant ecriture... puis le programme se
bloque et finit par quitter.
Le fichier ouvert est bien créé, mais rien n'y est écrit.

Précision : j'utilise Dev-C++ qui m'a déjà fait le coup d'utiliser
msvcrt.dll pour des fonctions de la bibliothèque standard.
Serait-il possible que le problème vienne de là? Et si oui, comment le
regler?

Merci de votre aide.

4 réponses

Avatar
Julien Gilli
On Sun, 31 Aug 2003 12:42:07 +0200, Nicolas Favre-Félix wrote:

Bonjour.


Bonjour,


J'ai un problème vraiment incompréhensible lors de l'écriture d'un
fichier. Voici le code:


[..snip..]

Je vois s'afficher derniere ligne avant ecriture... puis le programme se
bloque et finit par quitter.
Le fichier ouvert est bien créé, mais rien n'y est écrit.


Voici le test que j'ai effectué sur un système GNU/Linux (distribution
Debian) :

:/tmp$ cat test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main(int argc, char* argv[])
{
char* buffer;
FILE* f;
int nb_t, nb_v, nb_s;

nb_t = nb_v = nb_s = 42;

buffer = malloc(200 * sizeof(char));
sprintf(buffer, "%dn%dn%dn", nb_t, nb_v, nb_s); printf("buffer='%s',
taille=%dn", buffer, strlen(buffer));

if ((f = fopen("/tmp/test.txt", "w")) == NULL)
{
fprintf(stderr, "%sn", strerror(errno)); return EXIT_FAILURE;
}
if (fseek(f, 0, SEEK_SET) == -1)
{
fprintf(stderr, "%sn", strerror(errno)); return EXIT_FAILURE;
}

printf("derniere ligne avant ecriture...n"); if (fwrite(buffer,
sizeof(char),strlen(buffer), f) != strlen(buffer))
{
fprintf(stderr, "%sn", strerror(errno)); return EXIT_FAILURE;
}
if (fclose(f) == EOF)
{
fprintf(stderr, "%sn", strerror(errno)); return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
:/tmp$ gcc -Wall test.c -o test
:/tmp$ ./test
buffer='42
42
42
', taille=9
derniere ligne avant ecriture...
:/tmp$ cat test.txt 42
42
42
:/tmp$

On peut voir que le code ci-dessus correspond à peu de choses près au
code posté précédemment, et que cela fonctionne comme vous le
souhaiteriez, à priori.

Vous devriez, à mon avis, contrôler la valeur de retour de chaque appel
à une fonction d'entrée/sortie. Comme cela, vous serez à même
d'identifier le problème. Par exemple, il existe des fichiers sur
lesquels il n'est pas possible d'effectuer des déplacements de pointeur
courant (sous Unix, les fichiers spéciaux de type périphérique
caractère par exemple).

Précision : j'utilise Dev-C++ qui m'a déjà fait le coup d'utiliser
msvcrt.dll pour des fonctions de la bibliothèque standard. Serait-il
possible que le problème vienne de là? Et si oui, comment le regler?


Je ne sais pas, je pense vraiment qu'en contrôlant le code de retour de
vos appels aux fonctions de la bibliothèque standard, vous devriez
obtenir les informations qu'il vous manque.


--
char tmpbuf[100]; /* XXX this will break in about 2,500 years */
OpenBSD 3.3, /usr/src/sbin/newfs/mkfs.c
Julien Gilli

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', "Nicolas Favre-Félix" wrote:

Voici le code:

buffer = (char*)malloc(200 * sizeof(char)); // on alloue bien assez


Une façon compliquée d'écrire

char *buffer = malloc(200);

On a probablement besoin de connaitre la taille pour des contrôles. Une
constante ou une variable serait la bienvenue:

size_t const size = 200;
char *buffer = malloc (size);

Vérifier que buffer est <> de NULL avant de l'utiliser

sprintf(buffer, "%dn%dn%dn", nb_t, nb_v, nb_s);/


Ok, en admettant que 'nb_t' etc. sont de type 'int'. Veiller aussi à ce que
<stdio.h> soit bien inclus.

printf("buffer='%s', taille=%dn", buffer, strlen(buffer));


Le type de strlen() est 'size_t', or "%d" attend un 'int'. Le comportement
est indéfini.

printf("buffer='%s', taille=%un", buffer, (unsigned) strlen(buffer));

f = fopen(fichier, "w");// ouverture en écriture


Vérifier que f est non NULL.

fseek(f, 0, SEEK_SET); // pointe sur le début


Inutile (à supprimer)

printf("derniere ligne avant ecriture...n");
fwrite(buffer, sizeof(char),strlen(buffer), f); / plante!


Pas du C! Il faut 2 / (En C99)

fwrite (buffer, 1, strlen(buffer), f);

C'est à dire? Quelle est la valeur retournée par fwrite() ?

la chaine buffer est créée, puis j'y mets 3 nombres.


Comment?

j'ai en sortie :

buffer='104
1000
2000
', taille

Pile ce que je veux écrire bans le fichier.
Je vois s'afficher derniere ligne avant ecriture... puis le programme se
bloque et finit par quitter.
Le fichier ouvert est bien créé, mais rien n'y est écrit.

Précision : j'utilise Dev-C++ qui m'a déjà fait le coup d'utiliser
msvcrt.dll pour des fonctions de la bibliothèque standard.
Serait-il possible que le problème vienne de là? Et si oui, comment le
regler?


Je n'ai aucun problèmes avec ce code (C99, Dev-C++ 4.9.8.1):

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define fichier "data.txt"

int main (void)
{
int nb_t = 104;
int nb_v = 1000;
int nb_s = 2000;
char *buffer = malloc (200);

sprintf (buffer, "%dn%dn%dn", nb_t, nb_v, nb_s);
printf ("buffer='%s', taille=%dn", buffer, strlen (buffer));

FILE *f = fopen (fichier, "w"); // ouverture en écriture
fseek (f, 0, SEEK_SET); // pointe sur le début
printf ("derniere ligne avant ecriture...n");
fwrite (buffer, sizeof (char), strlen (buffer), f);
fclose (f);
system ("pause");
return 0;
}

buffer='104
1000
2000
', taille
derniere ligne avant ecriture...
Appuyez sur une touche pour continuer . . .

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Avatar
Bruno Desthuilliers
Nicolas Favre-Félix wrote:
Bonjour.

J'ai un problème vraiment incompréhensible lors de l'écriture d'un fichier.
Voici le code:


buffer = (char*)malloc(200 * sizeof(char)); // on alloue bien assez
sprintf(buffer, "%dn%dn%dn", nb_t, nb_v, nb_s);/
printf("buffer='%s', taille=%dn", buffer, strlen(buffer));

f = fopen(fichier, "w");// ouverture en écriture
fseek(f, 0, SEEK_SET); // pointe sur le début
printf("derniere ligne avant ecriture...n");
fwrite(buffer, sizeof(char),strlen(buffer), f); / plante!



[ laotseu]$ gcc -Wall -ansi -pedantic -o dev/testwrite
dev/testwrite.c
dev/testwrite.c:1: warning: type defaults to `int' in declaration of
`buffer'
dev/testwrite.c:1: warning: implicit declaration of function `malloc'
dev/testwrite.c:1: warning: initialization makes integer from pointer
without a
cast
dev/testwrite.c:1: initializer element is not constant
dev/testwrite.c:1: ISO C forbids data definition with no type or storage
class
dev/testwrite.c:1: parse error before '/' token
dev/testwrite.c:5: warning: type defaults to `int' in declaration of `f'
dev/testwrite.c:5: warning: implicit declaration of function `fopen'
dev/testwrite.c:5: `fichier' undeclared here (not in a function)
dev/testwrite.c:5: initializer element is not constant
dev/testwrite.c:5: ISO C forbids data definition with no type or storage
class
dev/testwrite.c:5: parse error before '/' token
dev/testwrite.c:5: stray '351' in program
dev/testwrite.c:6: stray '351' in program
dev/testwrite.c:8: parse error before "sizeof"
dev/testwrite.c:8: warning: type defaults to `int' in declaration of
`fwrite'
dev/testwrite.c:8: warning: type defaults to `int' in declaration of
`strlen'
dev/testwrite.c:8: warning: parameter names (without types) in function
declaration
dev/testwrite.c:8: warning: type defaults to `int' in declaration of `f'
dev/testwrite.c:8: parse error before ')' token

Merci de poster un code compilable (#includes, main() etc).

Bruno

Avatar
Yves ROMAN

Bonjour.

J'ai un problème vraiment incompréhensible lors de l'écriture d'un fichier.
Voici le code:

buffer = (char*)malloc(200 * sizeof(char)); // on alloue bien assez
sprintf(buffer, "%dn%dn%dn", nb_t, nb_v, nb_s);/
printf("buffer='%s', taille=%dn", buffer, strlen(buffer));

f = fopen(fichier, "w");// ouverture en écriture
fseek(f, 0, SEEK_SET); // pointe sur le début
printf("derniere ligne avant ecriture...n");
fwrite(buffer, sizeof(char),strlen(buffer), f); / plante!

la chaine buffer est créée, puis j'y mets 3 nombres.
j'ai en sortie :

buffer='104
1000
2000
', taille

Pile ce que je veux écrire bans le fichier.
Je vois s'afficher derniere ligne avant ecriture... puis le programme se
bloque et finit par quitter.
Le fichier ouvert est bien créé, mais rien n'y est écrit.



Pas d'erreur notée à part celles déjà signalées

Tu n'aurais pas oublié d'appeler fclose() avant la fin de ton programme ?
Si c'est le cas, c'est normal qu'il n'y ait rien dans ton fichier, car la
bibliothèque C gère un tampon d'écriture qu'il n'est écrit sur disque que sur
débordement ou sur appel de fflush() et fclose()

Essaye avec un fflush(f) ; après le fwrite.

Une autre erreur classique est d'appeler close() au lieu de fclose()