fscanf et fichier txt qui repond systematiquement 0 (sur du code pour pc)

Bonjour,

Je suis pas sur arduino pour cette … énervante affaire de fscanf.
Je m’explique, j’ai récupérer un code écrit par quelqu’un d’autre (du site cppfrance)

Il a écrit un trucs qui oblige a remplir manuellement un tableau par 64 lignes via des questions !! chiantissime à l’extrème.
Sur un autre fichier du même auteur, il arrive a écrire un trucs simple pour lire un TXT.
Par plus con qu’un autre (…) je réalise la copie de l’un à l’autre, je change le nom du fichier bien entendu.

Et là je constate qu’il (l’auteur d’origine) a dû comme moi maintenant s’arracher les cheveux pour un trucs pourtant simple…

FILE*matrice64e;
printf("Ouverture du fichier MATRICE64E pour le chargement des 64 elements :\n\n");
// *remplissage automatique des elements de la matrice de depart *
matrice64e = fopen("matrice64e.txt","r");
if (matrice64e==NULL) 
{
printf ("Erreur lors de la tentative d'ouverture du fichier matrice64e\n\n");
}
else
{

for(i=0;i<=7;i++){
	for(j=0;j<=7;j++)
 	{ 
		while(!feof(matrice64e)) 
 		{
			fscanf(matrice64e,"%d",&resultat[i][j]);
 		}		
 	}
 }
 fseek(matrice64e,0,SEEK_SET);
fclose(matrice64e);

Maintenant dite moi pourquoi je récupère a chaque fois uniquement des ZEROs dans resultat

Je précise que le txt existe bien,
qu’il ne contient pas que des zeros (b’ha oui)
qu’il y a des séparateur avec des espaces,
qu’il contient des entiers non signé,
et qu’il ne dépasse pas 64 nombres.
Que i et j existe, déclarer proprement plus haut dans le code
Que cette section de code recopier fonctionne bien ou je l’ai pris (si).

Et que je me suis aussi “amusé” à faire des modif de fscanf avec %d %ld %u, pour le fun si je puis dire !!
Sans resultat autres que ZERooo “O” Z.E.R.O ! Gnni

Pire j’ai chercher des exemples ici et là et rien ne cloche sauf a la rigueur “fseek(matrice64e,0,SEEK_SET);”
qui na pas vraiment de raison d’être puisque je ne recherche rien d’autre et que je referme le fichier sans le rouvrir !

2 solutions qui me viennent rapidement à l'esprit :

remplace :

fscanf(matrice64e,"%d",&resultat[i][j]);

par

fscanf(matrice64e,"%d",resultat[i][j]);

Et si çà ne fonctionne pas :

Essaye avec un truc du style :

char nombre[10];

fgets(matrice64e, 10, nombre);
resultat[i][j] = atoi(nombre);

à la place de cette ligne.

Tiens nous au jus.

Bonjour,

Donne nous un exemple de fichier texte qu’on sache à quoi il ressemble :wink:

Grag38 ton truc va lui coller une “segmentation fault” à l’exécution, fscanf attend un pointeur sur int, pas un int :wink:

Bon sinon voici un code qui marche (testé à l’instant) :

/* Includes */
#include <stdio.h>

/* Fonction principale */
int main(int argc, char** argv) {

	/* Variables de travail */
	FILE* fi; /* Fichier source */
	int matrice[8][8]; /* Matrice résultat */
	int i, j; /* Itérateurs */
	
	/* Test du nombre d'arguments CLI */
	if (argc < 2) {
		printf("USAGE %s <input file>", argv[0]);
		return 1;
	}
	
	/* Ouverture du fichier source */
	if ((fi = fopen(argv[1], "r")) == NULL) {
		perror("fopen");
		return 1;
	}
	
	/* Lecture des données du fichier source */
	for (i = 0; i < 8; ++i) {
		for (j = 0; j < 8; ++j) {
		
			/* Lecture de la valeur et test en cas d'erreur */
			if (fscanf(fi, "%d", &(matrice[i][j])) != 1) {
				printf("Donnée manquante à l'index (%d, %d) !", i, j);
				return 1;
			}
		}
	}
	
	/* Fermeture du fichier source */
	fclose(fi);

	/* Affichage des données de la matrice résultats */
	for (i = 0; i < 8; ++i) {
		for (j = 0; j < 8; ++j) {
			printf("%d ", matrice[i][j]);
		}
		puts("");
	}
	
	/* fin du programme */
	return 0;
}

Et un fichier texte de démo :

1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8

Hha vous n'aller pas me croire !!

J'ai changer un détaille qui n'aurai pas du avoir d’impact en principe ...et pourtant ! Et du coup je me demande toujours pourquoi il fonctionne sur le reste du code de Mr l'auteur d'origine. Sérieusement il a du tomber sur le même Hic que moi !

        do
        {
            fscanf(matrice64e,"%d",&resultat[i][j]);
        }while(feof(matrice64e)==1) ;

Remplacer un while(){} par un do{}while()

Pff ha ha ha ha Non mais sans blague !!!

J'ai changer le fichier matrice par une suite 1 2 3 4.... Puis j'ai constater que ma matrice tableau contenais un chiffre, ho mon dieu Un chiffre. Chiffre que j'ai rechercher par tâtonnement et figurez-vous qui correspondez à la dernière entrée dans le fichier, un "8".

Donc mystère et boule de gomme.

Heu dite moi .. je cherche quelque chose de simple. Pour effectuer une pause dans le déroulement du programme que je tripote, il me manque un petit quelque chose.

Je cherche a faire ceci : Ecran :

Pressez Espace pour continuer ...

Tout bête !

J'ai utiliser getchar() mais je me suis rendu compte qu'il demande a ce que je grappe la touche entrée pour fonctionner, getchar prend un code ascii et la touche entrée 2, total 3 code ascii !

Va voir là : http://ecrucru.free.fr/?page=pause

Merci

Autant le dire tout net ... fonctionne pas Je suis en mesure de tapper un paragraphe a l'écran sans sortir de la pause, sauf si je frappe entrée 2 fois. La première frappe provoque un retour charriot et la seconde permet a la suite de fonctionner.

J'ai tenter la version longue et la courte, system("PAUSE") avec variante vu ailleurs "cmd \c pause" Dans les 2 derniers cas avec "system", il répond "commande inconnu" à la compilation (je pense a une librairie mais cela me contrarie un brin de devoir en mettre une juste pour une commande).

Mystère et boule de gomme again ?

system(“pause”); c’est valable que sous windows avec l’include <Windows.h>.

Testé, approuvé et compatible tout OS :

#include <stdio.h>

void SystemPause() {
   char buf[255];
   fflush(stdin);
   puts("Appuyez sur une touche pour continuer...");
   gets(buf);
}

int main(void) {
  SystemPause();
  return 0;
}

Je rigole nerveusement ...

Je doit être maudit. Bon alors pour info et pour en être "sure" j'utilise Dec-c++ gratuit et frenchisé. Ton code comme le miens d'ailleurs fonctionne toujours en attendant une confirmation par la frappe de Entrée. Je suis capable de tapper un roman en guise de réponse !!

Du coup je suis aller dans le sens du problème ....

Note : Histoire de rigoler moi je suis du genre à écrire avec mes maigres connaissance du C en tappant ce qui suit, et le résultat à la même réaction qu'avec ta version !

void SystemPause()
{
   char magickey;
   printf("Appuyez sur Entree pour continuer...");
   do{
   fflush(stdin);
   magickey = getc(stdin);
  }while (magickey==13);
}

Du coup je zappe la question du "taper sur une touche"

Tu peut effectivement rentré du texte si tu veut, le principal c'est d'appuyé sur entrer. Tu veut quoi exactement ? Attendre l'appui sur la touche entrer uniquement sans saisie de texte ?

Ps : pour utiliser Dec-c++ ... cet IDE n'est plus du tout mis à jour depuis des années, il utilise même encore GCC 3.4 (on est à la 4.7 actuellement) ! Tu as eclipse (certes un peu lourd mais très complet) ou QtCreator qui intègre tout le nécessaire pour compiler avec un IDE récent.

Edit: ou tout simplement Code::Blocks (même si je en l'utilise pas personnellement)

Je voulais qu'il ne prenne que l'appui d'une touche sans confirmation par la touche entrée, espace,c,x,i,u, qu'importe. Et donc en ne trouvant pas de solution logique j'ai fini par me mettre "Entrée" et non plus "une touche".

Vois-tu je me suis tripoter du basic il y a belle lurette et je trouve étonnant de ne pas en avoir le pendant dans le langage C a l'époque du basic "inkey$" prenais une frappe du clavier en mémoire pour en vérifier ensuite la valeur ascii... bête comme tout! Sur un VIC-20 avec 6502 à 1mhz bon dieu la vieillerie !

Enfin bref...

Pour Dev-C++ je ne savais pas ... d'ailleurs en y regardant de plus près il a l'air d'être entre 2 chaises, j'ai deux version v4.9.9.2 officiel modifier par orwell v5.3.0.3 de novembre 2012 avec MinGW 4.7.0 Il y a donc un passionnée qui à repris le flambeau. En cherchant j'ai maintenant trouver dev-C++ 5.4.0 avec gcc 4.7.2 pas mauvais je pense, j'imagine, j'extrapole, je suppute.

Merci pour ton indulgence

g1_8008: Je voulais qu'il ne prenne que l'appui d'une touche sans confirmation par la touche entrée, espace,c,x,i,u, qu'importe. Et donc en ne trouvant pas de solution logique j'ai fini par me mettre "Entrée" et non plus "une touche".

Fallait le dire plus tôt :grin: http://www.cplusplus.com/reference/cstdio/getchar/

g1_8008: Pour Dev-C++ je ne savais pas ... d'ailleurs en y regardant de plus près il a l'air d'être entre 2 chaises, j'ai deux version v4.9.9.2 officiel modifier par orwell v5.3.0.3 de novembre 2012 avec MinGW 4.7.0 Il y a donc un passionnée qui à repris le flambeau. En cherchant j'ai maintenant trouver dev-C++ 5.4.0 avec gcc 4.7.2 pas mauvais je pense, j'imagine, j'extrapole, je suppute.

Tient tient, effectivement quelqu'un a repris le projet (bonne nouvelle) :

As of 2012-10-01, this project may now be found at http://sf.net/projects/orwelldevcpp/.

Enfin (ou plutôt "de nouveau") une alternative sympa à code::block !

Tu va me comprendre pour un être démoniaque hanté par un adepte rendu fou par du cobol ou que sais-je. Ou du la série des SF galactica, Ohh dieu de kobol ... oui oui monsieur je devient fou.

J'ai déjà tester getchar en première tentative et là j'ai repris les lignes de l'exemple à la virgule exacte.

Non seulement la frappe de entrée reste obligatoire mais en complément tel la cerise sur le gâteaux le retour chariot d'un printf qui suit ré-imprime le point et à l'image j'ai donc :

Blabla presse sur '.' pour la suite ... . (et entrée donc) . bla bla la suite qui l'affiche

Je ne me pose plus du tout de question, même le pourquoi de revoir le . avant le printf ne me dérange pas, gnon gnon!

Extraordinaire n'est ce pas Ha haaa donne moi un entonnoir.. je repeint le plafond.

Je viens de tester le code d’exemple et j’ai le même type de fonctionnement “bizarre”.
Mais j’ai peu être un début d’explication du pourquoi.

Stdin est un flux bufferisé, le buffer n’est vidé qu’au moment d’un \n (enter).
Or getchar() attend un caractère sur stdin, mais pour que getchar() puisse lire quelque chose il faut que le buffer soit vidé par un \n.
Du coup l’écho local de la console affiche le texte entrée, puis un fois enter appuyé le buffer est vidé et le putchar() affiche une seconde fois le texte jusqu’au point.

Essaye ce code qui désactive l’echo local et le buffering de stdin :

#include <stdio.h>
#include <unistd.h>
#include <termios.h>

int main()
{
    struct termios old_tio, new_tio;
    unsigned char c;

    /* get the terminal settings for stdin */
    tcgetattr(STDIN_FILENO,&old_tio);

    /* we want to keep the old setting to restore them a the end */
    new_tio = old_tio;

    /* disable canonical mode (buffered i/o) and local echo */
    new_tio.c_lflag &=(~ICANON & ~ECHO);

    /* set the new settings immediately */
    tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);

    /* Typewriter */
    puts ("Enter text. Include a dot ('.') in a sentence to exit:");
    do {
        c=getchar();
        putchar (c);
    } while (c != '.');

    /* restore the former settings */
    tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);

    return 0;
}

J’ai une vague de déprime qui parcours mon corps !

Dev-C++ n’inclus pas termios.h et pas non plus ansi.h
Oui mais bon j’ai trouver le premier puis le second
Car le premier en a appeler indirectement un second bien caché !
Seulement voilà je me suis fendu d’un copier coller à l’arrache qui n’arrange pas vraiment non affaire.
Ne sachant pas inclure une librairie proprement dans dev-c++

Le tout me génère un message comme quoi …

[Linker error] C:\Users\Portable\AppData\Local\Temp\ccGRi3iL.o:CODAGE DECODAGE HUFFMAN version 2.cpp:(.text+0x9b8): undefined reference to tcgetattr(int, termios*)' [Linker error] C:\Users\Portable\AppData\Local\Temp\ccGRi3iL.o:CODAGE DECODAGE HUFFMAN version 2.cpp:(.text+0x9ff): undefined reference to tcsetattr(int, int, termios const*)’
[Linker error] C:\Users\Portable\AppData\Local\Temp\ccGRi3iL.o:CODAGE DECODAGE HUFFMAN version 2.cpp:(.text+0xa46): undefined reference to tcsetattr(int, int, termios const*)' bad reloc address 0x0 in section .pdata’
Invalid operation

Je suis pas un pro, vraiment pas, mais je devrai me faire betatesteur j’ai mes chances!
Il y a quelques jours je suis même tomber sur un bug, d’ailleurs j’ai inclus la solution provisoire.
(autre forum autre pseudo)
Au secours

g1_8008:
Dev-C++ n’inclus pas termios.h et pas non plus ansi.h

P*tain parfois je suis vraiment un boulet !
<termios.h> c’est pour la gestion des terminaux sous linux, sous windows c’est pas du tout la même chose.

Sous windows c’est <conio.h> :

getch - Reads a character directly from the console without buffer, and without echo.

J'ai modifier le p'tit détail malheureux...

Et le termios passa en conio, dit t'il à voix basse. OOh ciel oooh misère, que faire, sermonna t'il les yeux pointer vers le plafond ! En conséquence de cette inconséquence, que voilà une nouvelle sentence, trois petit points.

Et hop ... maintenant la totalité des lignes ne sont plus reconnu que comme des variables non déclaré. Marquer d'un beau rouge sacrilège "... not declared in this scope"

Note au psy: Ah haaa donne moi une arme à feux que je me tire une balle dans le pieds, de suite. Ou non plutôt cette mort douce... ou cache tu donc ton flacon de vitriole.

L'humour me tiendrai par la jambe ? ça pique

Note : aussi modifier dans "struct conio ..."

Code compilé avec gcc sans probléme et 100% fonctionnel sous windows :

#include <stdio.h>
#include <conio.h>

int main()
{
    unsigned char c;

    puts ("Enter text. Include a dot ('.') in a sentence to exit:");
    do {
        c=getch();
        putch(c);
    } while (c != '.');

    return 0;
}

Merci.

Plus besoin de faire entrée (ouf!) Mais j'ai toujours le point parasite qui retourne à la ligne.

Rassure toi moi aussi j'en ai ras le bol, a la limite j'avais envie de l'imprimer pour mâché de papier après ! (imagine toi un mec glauque mâchouillant de papier avec les yeux du même glauque) Mon ultime bidouille (si j'ai envie d'y toucher) sera de mettre un espace, au moins lui ne va pas faire tache à l'écran.

Si tu vires le "putch(c);" plus rien doit s'afficher ... sinon je bouffe mon chapeau ! (ok j'avoue je prend pas trop de risque vu que j'en ai pas :grin:)