écrire fichier segmentation fault ?

Le
pere.noel
bon, je continue mes périgrinations C-esques.

je lis un tuto sur le net :
<http://irc.essex.ac.uk/www.iota-six.co.uk/c/i4_fwrite_fscanf_fprintf.as
p>

qui donne le code suivant (au complet) :

file.c -
#include <stdio.h>

int main() {
FILE *sourceFile;
FILE *destinationFile;
char *buffer;
int n;

sourceFile = fopen("file.c", "r");
destinationFile = fopen("file2.c", "w");

if(sourceFile==NULL) {
printf("Error: can't access file.c.");
return 1;
}
else if(destinationFile==NULL) {
printf("Error: can't create file for writing.");
return 1;
}
else {
n = fread(buffer, 1, 1000, sourceFile); /* grab all the text */
fwrite(buffer, 1, n, destinationFile); /* put it in file2.c */
fclose(sourceFile);
fclose(destinationFile);

destinationFile = fopen("file2.c", "r");
n = fread(buffer, 1, 1000, destinationFile); /* read file2.c */
printf("%s", buffer); /* display it all */

fclose(destinationFile);
return 0;
}
}


donc ça lit le fichier source "file.c" et ça écrit dans le fichier
destination "file2.c".

mais, au runtime j'ai droit à une "segmentation fault" dont je ne vois
pas la raison
--
une bévue
Vos réponses Page 1 / 3
Trier par : date / pertinence
pere.noel
Le #964583
Une bévue
char *buffer;


juste un malloc et c'est OK )))

--
une bévue

Eric Levenez
Le #964582
Le 17/09/06 11:35, dans

bon, je continue mes périgrinations C-esques.

je lis un tuto sur le net :
<http://irc.essex.ac.uk/www.iota-six.co.uk/c/i4_fwrite_fscanf_fprintf.as
p>


Mais faut pas lire des choses comme cela !

Cette exemple est ce qu'il NE FAUT PAS FAIRE !

qui donne le code suivant (au complet) :

--- file.c -------------------------------------------------------------
#include
int main() {


int main(void) {

FILE *sourceFile;
FILE *destinationFile;
char *buffer;


buffer n'est pas initialisé

int n;

sourceFile = fopen("file.c", "r");
destinationFile = fopen("file2.c", "w");

if(sourceFile==NULL) {
printf("Error: can't access file.c.n");
return 1;


return EXIT_FAILURE;

Si le premier fichier n'existe pas mais le second existe, alors on a ouvert
le second, mais on ne l'a pas fermé. Mauvais.

}
else if(destinationFile==NULL) {


Le "else" est inutile à cause du return précédent

printf("Error: can't create file for writing.n");
return 1;


return EXIT_FAILURE;

Il faudrait fermer là le premier fichier au lieu de le laissé ouvert

}
else {


Le "else" est inutile à cause du return précédent

n = fread(buffer, 1, 1000, sourceFile); /* grab all the text */


On lit 1000 char dans un buffer qui n'a pas été alloué, d'où plantage

"n" n'est pas testé pour savoir si on a eu une erreur.

fwrite(buffer, 1, n, destinationFile); /* put it in file2.c */


On écrit ce qu'on a lu (si on a eu la chance de ne pas avoir d'erreur), mais
on ne vérifie pas si on a bien écrit.

fclose(sourceFile);
fclose(destinationFile);

destinationFile = fopen("file2.c", "r");


On ne teste pas le code de retour de fopen

n = fread(buffer, 1, 1000, destinationFile); /* read file2.c */


On lit des données (si on n'a pas d'erreur) dans un buffer non alloué

printf("%s", buffer); /* display it all */


Il faudrait faire un fflush(stdout) pour être sûr que les caractères
bufferisés sont bien envoyé (même si exit le fait normalement).


fclose(destinationFile);


Si le fopen a raté, alors il ne faut pas faire le flcose

return 0;
}
}
------------------------------------------------------------------------

donc ça lit le fichier source "file.c" et ça écrit dans le fichier
destination "file2.c".


Donc ce code fait n'importe quoi.

mais, au runtime j'ai droit à une "segmentation fault" dont je ne vois
pas la raison...


C'est un jeu des 1000 erreurs ?

--
Éric Lévénez -- Unix is not only an OS, it's a way of life.

Eric Levenez
Le #964581
Le 17/09/06 11:47, dans

Une bévue
char *buffer;


juste un malloc et c'est OK )))


Ça corrige juste 1 erreur, il en reste 999 à trouver...

--
Éric Lévénez -- Unix is not only an OS, it's a way of life.


pere.noel
Le #964579
Eric Levenez
Ça corrige juste 1 erreur, il en reste 999 à trouver...


999 erreurs sur 35 lignes, l'auteur est un champion alors...
--
une bévue

pere.noel
Le #964580
Eric Levenez

Mais faut pas lire des choses comme cela !


beuh, comme je le sais "a priori" ???

Cette exemple est ce qu'il NE FAUT PAS FAIRE !



c'est didactique, sans doute )))

<snip/>

return 1;


return EXIT_FAILURE;

Si le premier fichier n'existe pas mais le second existe, alors on a ouvert
le second, mais on ne l'a pas fermé. Mauvais.


vouais...


}
else if(destinationFile==NULL) {


Le "else" est inutile à cause du return précédent


vouais...

printf("Error: can't create file for writing.n");



<snip/>


fclose(destinationFile);


Si le fopen a raté, alors il ne faut pas faire le flcose


bon ok merci, je vais mettre ça "au propre"...


return 0;
}
}
------------------------------------------------------------------------

donc ça lit le fichier source "file.c" et ça écrit dans le fichier
destination "file2.c".


Donc ce code fait n'importe quoi.

mais, au runtime j'ai droit à une "segmentation fault" dont je ne vois
pas la raison...


C'est un jeu des 1000 erreurs ?


pas du tout, pas évident, pour moi, à voir toutes erreurs...

notes que j'ai vu pire dans un tuto...
--
une bévue


Pierre Maurette
Le #964578
[...]
return EXIT_FAILURE;

Si le premier fichier n'existe pas mais le second existe, alors on a ouvert
le second, mais on ne l'a pas fermé. Mauvais.


Non.
La norme est claire. Contrairement à la désallocation de la mémoire,
les streams sont fermés à la sortie normale du programme:
§7.20.4.3.4 (concerne exit()):
"Next, all open streams with unwritten buffered data are flushed, all
open streams are closed, and all files created by the tmpfile function
are removed."

Et la norme ramène à exit(int) le return int et l'atteinte du } dans
main().

[...]

printf("Error: can't create file for writing.n");
return 1;


return EXIT_FAILURE;

Il faudrait fermer là le premier fichier au lieu de le laissé ouvert


Non non. Voir plus haut.

--
Pierre Maurette


Eric Levenez
Le #964577
Le 17/09/06 18:09, dans Maurette »

Si le premier fichier n'existe pas mais le second existe, alors on a ouvert
le second, mais on ne l'a pas fermé. Mauvais.


Non.
La norme est claire.


Oui, je sais très bien tout cela. Je n'ai pas dit que ce n'était pas
conforme, juste que c'était mauvais. Il faut apprendre à fermer ce que l'on
a ouvert. Et ce que l'auteur de l'immonde code à fait dans main, il le fait
aussi dans toute autre fonction. Je le répète : c'est mauvais.

--
Éric Lévénez -- Unix is not only an OS, it's a way of life.


Eric Levenez
Le #964576
Le 17/09/06 16:18, dans

Eric Levenez
Mais faut pas lire des choses comme cela !


beuh, comme je le sais "a priori" ???


Tu regardes la façon dont le main est déclaré. Normalement cela donne tout
de suite le niveau du mec. Après tu regardes si les codes de retour des
fonctions sont testés. Si ce n'est pas bon, tu vas sur un autre site.

--
Éric Lévénez -- Unix is not only an OS, it's a way of life.


Eric Levenez
Le #964575
Le 17/09/06 16:18, dans

Eric Levenez
Ça corrige juste 1 erreur, il en reste 999 à trouver...


999 erreurs sur 35 lignes, l'auteur est un champion alors...


Ce genre de champion pullulent sur Internet. Normalement tout étudiant sur
un langage donné, fera sa propre page web sur le sujet, truffée d'erreur, et
considèrera que son tutorial est le meilleur au monde.

--
Éric Lévénez -- Unix is not only an OS, it's a way of life.


pere.noel
Le #964405
Eric Levenez

Tu regardes la façon dont le main est déclaré. Normalement cela donne tout
de suite le niveau du mec. Après tu regardes si les codes de retour des
fonctions sont testés. Si ce n'est pas bon, tu vas sur un autre site.


ce qui était tout à fait le cas )))

ps j'ai trouvé une lib btree...
dont celle de ruby en est inspirée...
--
une bévue

Publicité
Poster une réponse
Anonyme