Pb fichier, langage C
Résolu
Utilisateur anonyme
-
lucieb31 Messages postés 363 Statut Membre -
lucieb31 Messages postés 363 Statut Membre -
Bonjour,
Mon programme plante et je n'arrive pas à en trouver la raison.
Code de la fonction :
Un exemple de sortie :
(sans plus, il plante au fprintf())
J'ai essayé de changer de mode w en wb (avec la fonction fwrite), même plantage au même endroit.
Quelqu'un voit le problème dans mon code ?
Merci d'avance
Mon programme plante et je n'arrive pas à en trouver la raison.
Code de la fonction :
void hexaToAscii(char *filenameIn, char *filenameOut)
{
FILE *in = fopen(filenameIn, "rb");
FILE *out = fopen(filenameOut, "w");
char c, read[2], str[3];
int nb;
if(!in || !out)
{
printf("\nerreur");
return;
}
nb = fread(read, 2, 1, in);
while(nb != 0)
{
str[0] = read[0];
str[1] = read[1];
str[2] = '\0';
printf("\n%s", str);
sscanf(str, "%x", &c);
printf("\nsscanf() -> %c", c);
fprintf(out, "%c", c);
printf("\nfprintf()");
nb = fread(read, 2, 1, in);
printf("\nfread()");
}
fclose(out);
fclose(in);
}
Un exemple de sortie :
41 sscanf() -> A
(sans plus, il plante au fprintf())
J'ai essayé de changer de mode w en wb (avec la fonction fwrite), même plantage au même endroit.
Quelqu'un voit le problème dans mon code ?
Merci d'avance
A voir également:
- Pb fichier, langage C
- Fichier bin - Guide
- Fichier epub - Guide
- Fichier rar - Guide
- Comment réduire la taille d'un fichier - Guide
- Fichier .dat - Guide
4 réponses
Salut,
Pas étonnant, tu mets : sscanf(str, "%x", &c); alors que c est un char.
Les octets supplémentaires vont déborder et récrire dans la pile. Ainsi l'adresse du pointeur in ne sera plus la bonne. Et lors de la prochaine lecture par fread, cela fera un joli segfault.
A la place de char c, utilise unsigned int c (le format %x attend un type unsigned int).
Cela devrait mieux fonctionner.
De plus, while(nb != 0) est un peu dangereux. Il vaudrait mieux utiliser while(nb==1) puisque fread renvoie le nombre d'éléments lus. S'il y a une erreur ou la fin du fichier est atteinte, la valeur de retour sera plus petit que 0,sans forcément être nulle.
Cdlt
Pas étonnant, tu mets : sscanf(str, "%x", &c); alors que c est un char.
Les octets supplémentaires vont déborder et récrire dans la pile. Ainsi l'adresse du pointeur in ne sera plus la bonne. Et lors de la prochaine lecture par fread, cela fera un joli segfault.
A la place de char c, utilise unsigned int c (le format %x attend un type unsigned int).
Cela devrait mieux fonctionner.
De plus, while(nb != 0) est un peu dangereux. Il vaudrait mieux utiliser while(nb==1) puisque fread renvoie le nombre d'éléments lus. S'il y a une erreur ou la fin du fichier est atteinte, la valeur de retour sera plus petit que 0,sans forcément être nulle.
Cdlt
"tu mets : sscanf(str, "%x", &c); alors que c est un char"
En effet mais comme je ne lui donne que 2 caractères en hexa je pensais que ça irait. En fait je n'avais pas pensé au débordement.
Je me suis en fait rendu compte qu'un sscanf(str, "%02x", &c); passe bien. J'aurais dû être plus rigoureux dans mon code pour le compilo :).
Merci
En effet mais comme je ne lui donne que 2 caractères en hexa je pensais que ça irait. En fait je n'avais pas pensé au débordement.
Je me suis en fait rendu compte qu'un sscanf(str, "%02x", &c); passe bien. J'aurais dû être plus rigoureux dans mon code pour le compilo :).
Merci
dsl je me suis trompé, c'est le mode wt que je voulais dire
Eh bien tes profs ne connaissent pas la norme.
Voici un extrait de la norme C99 pris sur le site officiel (http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf pour t'en convaincre (il en va de même pour les autres).
Comme tu peux le voir, aucune mention du "t". Preuve que cela n'est pas standard. Pour le mode texte, a, w et r sont largement suffisant.
Voici un extrait de la norme C99 pris sur le site officiel (http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf pour t'en convaincre (il en va de même pour les autres).
The argument mode points to a string. If the string is one of the following, the file is
open in the indicated mode. Otherwise, the behavior is undefined.231)
open text file for reading
r
truncate to zero length or create text file for writing
w
append; open or create text file for writing at end-of-file
a
open binary file for reading
rb
truncate to zero length or create binary file for writing
wb
append; open or create binary file for writing at end-of-file
ab
open text file for update (reading and writing)
r+
truncate to zero length or create text file for update
w+
append; open or create text file for update, writing at end-of-file
a+
231) If the string begins with one of the above sequences, the implementation might choose to ignore the
remaining characters, or it might use them to select different kinds of a file (some of which might not
conform to the properties in 7.19.2).
r+b or rb+ open binary file for update (reading and writing)
w+b or wb+ truncate to zero length or create binary file for update
a+b or ab+ append; open or create binary file for update, writing at end-of-file
Comme tu peux le voir, aucune mention du "t". Preuve que cela n'est pas standard. Pour le mode texte, a, w et r sont largement suffisant.
merci pour cet eclaiciement, mais alors comment cela ce fait il qu'il n'y ai pas d'erreur lors de la compilation ?
mais alors comment cela ce fait il qu'il n'y ai pas d'erreur lors de la compilation ?
Tout d'abord tout dépend du compilateur que tu utilises. Certain respecte la norme, d'autre non. Ensuite, si certaines choses peuvent être détectées par le compilateur comme (void main au lieu d'int main, etc.), pour d'autre cas c'est beaucoup plus dur à détecter, notamment pour le code dynamique (arguments et compagnie).
Tout d'abord tout dépend du compilateur que tu utilises. Certain respecte la norme, d'autre non. Ensuite, si certaines choses peuvent être détectées par le compilateur comme (void main au lieu d'int main, etc.), pour d'autre cas c'est beaucoup plus dur à détecter, notamment pour le code dynamique (arguments et compagnie).
Le mode rw n'existe pas ;-))). Soit le mode r+, soit w+.