Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

écrire fichier segmentation fault ?

23 réponses
Avatar
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.\n");
return 1;
}
else if(destinationFile==NULL) {
printf("Error: can't create file for writing.\n");
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

10 réponses

1 2 3
Avatar
pere.noel
Une bévue wrote:

char *buffer;


juste un malloc et c'est OK )))

--
une bévue

Avatar
Eric Levenez
Le 17/09/06 11:35, dans
<1hlt3h3.u6mtczr02lt5N%, « Une bévue »
a écrit :

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 <stdio.h>

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 -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
Eric Levenez
Le 17/09/06 11:47, dans
<1hlt4pw.1bldzas91z415N%, « Une bévue »
a écrit :

Une bévue wrote:

char *buffer;


juste un malloc et c'est OK )))


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

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
pere.noel
Eric Levenez wrote:

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


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

Avatar
pere.noel
Eric Levenez wrote:


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


Avatar
Pierre Maurette
[...]
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


Avatar
Eric Levenez
Le 17/09/06 18:09, dans , « Pierre
Maurette » a écrit :


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 -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Eric Levenez
Le 17/09/06 16:18, dans
<1hltgrc.1j328871aptwh5N%, « Une bévue »
a écrit :

Eric Levenez wrote:

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 -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Eric Levenez
Le 17/09/06 16:18, dans
<1hltgod.1sttcuc1p2wv17N%, « Une bévue »
a écrit :

Eric Levenez wrote:

Ç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 -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
pere.noel
Eric Levenez wrote:


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

1 2 3