Probleme avec getc sur windows en c
RésoluSerpentGentil87 Messages postés 7 Date d'inscription mercredi 12 juin 2024 Statut Membre Dernière intervention 30 juin 2024 - 30 juin 2024 à 14:27
- Probleme avec getc sur windows en c
- Clé windows 10 gratuit - Guide
- Montage video windows - Guide
- Windows ne démarre pas - Guide
- Windows 12 - Accueil - Windows
- Installer windows 11 sur pc non compatible - Accueil - Windows
10 réponses
13 juin 2024 à 08:18
bonjour,
serait-il possible de partager le code de ton programme?
13 juin 2024 à 08:26
Si tu lis du texte, tu ne peux pas utiliser ftell() pour déterminer le nombre de caractères lus, ni considérer ftell() comme te retournant la position dans le fichier.
13 juin 2024 à 12:58
Salut SerpentGentil87,
Les comportements de getc() et de ftell() sont expliqués dans leur documentation respective.
Si cela ne répond pas à la question, il va falloir fournir ton code et des explications plus claires.
Modifié le 13 juin 2024 à 17:09
Bonjour, merci de vos réponses.
J'ai créer ce tout petit code pour tester la lecture en dehors des perturbations possibles de mon gros programme et j'ai toujours le même problème.
Voici le petit code :
#include <stdio.h>
int main() {
FILE* fichier = fopen("Base2.bin", "r");
int tmp;
printf("%d\n", ftell(fichier));
tmp = fgetc(fichier);
printf("%d\n", ftell(fichier));
tmp = fgetc(fichier);
printf("%d\n", ftell(fichier));
fclose(fichier);
}
C'est bien car je n'ai pas trouvé dans les spécifications des fonctions concernant ce problème que j'ai posté ma demande ici.
Par exemple avec un fichier constitué de 560 caracteres, le programme retourne :
0
443
444
Alors que d'après ce que je lis partout, il aurait du retourner :
0
1
2
13 juin 2024 à 17:49
Je ne sais pas où tu lis quoi.
La spécification de ftell() indique clairement que le résultat n'a pas de signification dans le cas d'un fichier texte.
Dans quel but utilises-tu ftell()?
13 juin 2024 à 18:32
Pour connaitre ma position dans le fichier. Je fais comment sinon?
14 juin 2024 à 09:28
Pourquoi veux-tu connaitre ta position?
Tu pourrais peut-être compter le nombre de caractères obtenus.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question13 juin 2024 à 20:23
J'ai aussi oublié de dire que j'ai compilé tous mes programmes avec gcc.
Modifié le 14 juin 2024 à 19:20
Salut SerpentGentil87,
Merci pour ton code minimal, qui est utile pour comprendre ton problème.
Sous mon Linux ton programme retourne bien 0, 1, 2, mais comme cela a été dit à plusieurs reprises, la spécification précise bien que ftell() ne retourne pas une valeur fiable lorsque tu travailles sur un fichier ouvert comme un fichier texte, ce que tu fais lorsque tu utilises le spécificateur "r" avec fopen().
https://cplusplus.com/reference/cstdio/fopen/
On ne sais pas ce que contient "Base2.bin" (ni si son contenu est bien "binaire"), ni pourquoi tu tiens à avoir cette information.
Essayes de l'ouvrir avec "rb".
Par ailleurs, tu pourrais utiliser un fread() pour lire ton octet, et un type unsigned char pour stocker ta donnée binaire.
https://cplusplus.com/reference/cstdio/fread/
Cela donnerait :
#include <stdio.h> int main(void) { FILE * fichier = fopen("Base2.bin", "rb"); unsigned char tmp; printf("%ld\n", ftell(fichier)); fread(&tmp, 1, 1, fichier); printf("%ld\n", ftell(fichier)); fread(&tmp, 1, 1, fichier); printf("%ld\n", ftell(fichier)); fclose(fichier); return 0; }
Ce n'est pas très optimisé car il serait mieux de lire un bloc d'octets d'un coup, mais, pour l'exemple, cela devrait retourner le résultat que tu attends.
17 juin 2024 à 20:50
Bonjour, merci de vos réponses.
Ouvrir le fichier avec l'option rb a effectivement réglé le problème.
Cependant je n'ai toujours pas compris la différence entre un fichier texte et un fichier binaire. De plus j'ai lu que fread et getc ne devaient pas être utilisés simultanéments. Quelle est la différence entre les deux?
Modifié le 20 juin 2024 à 13:12
Bonjour SerpentGentil87,
Ouvrir le fichier avec l'option rb a effectivement réglé le problème
Oui, parce que tu as ouvert ton fichier en tant que flux binaire.
Je pense que tu as résolu le problème pour lequel tu postais ta question initiale. Peux-tu passer ce fil de discussion en "résolu" ?
je n'ai toujours pas compris la différence entre un fichier texte et un fichier binaire
C'est un raccourci de langage car en réalité tous les fichiers sont stockés sous forme "binaire". Cependant les "fichiers texte" sont conçus pour contenir des données correspondant à des caractères affichables, des caractères "blancs" (espaces, tabulations), et d'autres caractères "blancs" particuliers que sont les retours à la ligne, avec une spécificité sous Windows qui est que les retours à la ligne sont encodés avec deux caractères \r\n et le reste du monde juste \n (les versions anciennes des OS Mac jusqu'à OS 9 utilisaient seulement \r pour signifier le retour à la ligne, ce n'est plus le cas et c'est juste \n depuis que MacOS est basé sur l'implémentation BSD d'Unix).
Pour gérer ces particularités, la bibliothèque standard du langage C adapte le fonctionnement des fonctions de lecture et écriture selon le mode d'ouverture du fichier, binaire ou texte, et dispose de fonctions permettant comme fscanf() permettant de rechercher dans le flux du texte correspondant aux spécificateurs de format en ignorant les caractères blancs, de fonctions comme fgets() qui comprennent le concept de ligne (le compilateur pour tel système gérant les idiosyncrasies de l'OS sur comment on signifie qu'on passe à une ligne suivante), etc.
j'ai lu que fread et getc ne devaient pas être utilisés simultanéments
Ah, quelle est ta source ?
Quelle est la différence entre les deux
fread() est conçue pour lire des données en bloc dans un flux binaire et les stocker dans un tampon mémoire (ton tampon mémoire peut faire 1 byte ou être aussi grand que ce que ton compilateur peut adresser sur ta machine).
fgetc() est conçue pour lire un seul byte dans un flux ouvert.
Elles ont des usages différentes, une syntaxe différente et des résultats différents. Vois les page de manuel de ces deux fonctions.
Si tu te contentes de lire un seul byte, le résultat sera le même, car fgetc() ne fait aucune transformation sur le "caractère" (le byte) qu'elle lit, tout comme fread() qui lit les données brutes binaires enregistrées.
Tu peux lire un "fichier texte" avec fread(). Les données récupérées dans le tampon seront des données brutes et les caractères "blancs" y compris les caractères de retours à la ligne figureront de façon brute dans le tampon. Pour interpréter le contenu du tampon en tant que texte, ou lignes de texte, il faudra retraiter le tampon.
Tu peux aussi lire un "fichier binaire" avec fgetc(), byte par byte. Ce n'est pas très efficace car tu fais un appel système par appel à fgetc() (alors que fread() est optimisée et conçue pour lire des blocs de données), mais cela marchera.
Par exemple, le code suivant, tiré de ce post sur SO par l'utilisateur Mike, copie un fichier .jpg à coups de fgetc() et de fputc() :
int main() { FILE * fptr = fopen("small_pic.jpg", "rb"); // open existing binary picture char buffer[10000] = {0}; // the pic is 6kb or so, so 10k bytes will hold it FILE * fptr2 = fopen("new_small_pic.jpg", "wb"); // open a new binary file // for our copy of the pic unsigned long fileLen; unsigned long counter; fseek(fptr, 0, SEEK_END); fileLen=ftell(fptr); // get the exact size of the pic fseek(fptr, 0, SEEK_SET); for(counter=0; counter<fileLen; counter++) fputc(fgetc(fptr),fptr2); // read each byte of the small_pic.jpg and make // a new pic from it fclose(fptr); fclose(fptr2); return 0; }
(Licence CC BY-SA 3.0 par son auteur)
24 juin 2024 à 18:49
Bonjour, merci de ta réponse
J'ai vu que les deux fonction ne pouvaient pas être mélangés sur ce site : https://www.man-linux-magique.net/man3/gets.html
Sinon je pense avoir tout compris.
Merci!!!
Je peux marquer cette discution comme résolue?
Modifié le 24 juin 2024 à 19:14
J'ai vu que les deux fonction ne pouvaient pas être mélangés sur ce site : https://www.man-linux-magique.net/man3/gets.html
SI c'est ce passage :
Il est fortement déconseillé de mélanger les appels aux fonctions de
lecture de la bibliothèque stdio avec les appels aux fonctions de
lecture bas-niveau read(2) sur le descripteur de fichier associé au
flux. Les résultats sont indéfinis, et très probablement indésirables.
il parle de read() qui est une fonction accessible par unistd.h, et non de fread() qui relève de stdio.h
Sinon je pense avoir tout compris.
Merci!!!
Je peux marquer cette discution comme résolue?
Oui ! Tu fais cela sur ton sujet initial, en cliquant sur "Résolu".
30 juin 2024 à 14:27
Bon alors merci!!!