Probleme avec fgets
Répondre à la discussion
Affichage des résultats 1 à 17 sur 17

Probleme avec fgets



  1. #1
    deyni

    Probleme avec fgets


    ------

    Bonjour,

    J'ai fais ce code(qui est un sous code en fait):
    Ici, il faut saisir des nombres tant que l'utilisateur ne saisit pas la lettre "f"

    Code:
    char c = 'a';	
    	while (c != 'f') {
    			
    			printf("Veuillez saisir un nombre\n");
    			//scanf("%c", &c);
    			//gets(&c);
    			fgets(&c, sizeof(char) , stdin);
    			printf("%c\n", c);
    			printf("\n");
    	}
    Il part en boucle infinni.
    Mais:
    Si je mets 100 a la place de sizeof(char) ça "marche".
    Si j'entre 44( c = 44), il ne conserve que le premier chiffre.
    Même problème avec gets.

    Merci de votre aide.

    -----
    Deynid'oiseaux partout !! :rire:

  2. #2
    grosmatou75001

    Re : Probleme avec fgets

    Tu utilises mal fgets. c doit être une chaîne de caractères et en deuxième argument il faut mettre la longueur maxi de cette chaîne. http://www.cplusplus.com/reference/cstdio/fgets/ Idem pour gets. Ca fait un moment que je n'ai plus touché à ces trucs mais scanf ne convient pas? Ou alors http://www.cplusplus.com/reference/cstdio/fgetc/ ?

  3. #3
    grosmatou75001

    Re : Probleme avec fgets

    Il y a aussi getch() et getche(). Le choix est large et le sujet bien connu, un moteur de recherche te renseignera.

  4. #4
    deyni

    Re : Probleme avec fgets

    Bonjour,

    merci de votre réponse.
    J'ai lu que fgets marche aussi pour les caractères seuls....Peut-être un cas particulier.
    scanf marche, mais très mal, car le retour à la ligne(\n) est pris en compte, donc si on saisi 5, il tourne 2 fois, la première pour 5, la seconde pour \n
    Quand à getch et getche, sont des fonctions inconnus selon mes bibliothèques.

    fgetc ne convient à mon problème, car elle retourne un nombre


    Alors comment faire, les recherches sur internet sont peu fructueuses....
    Deynid'oiseaux partout !! :rire:

  5. A voir en vidéo sur Futura
  6. #5
    grosmatou75001

    Re : Probleme avec fgets

    Citation Envoyé par deyni Voir le message
    scanf marche, mais très mal, car le retour à la ligne(\n) est pris en compte, donc si on saisi 5, il tourne 2 fois, la première pour 5, la seconde pour \n
    fgetc fait la même chose mais il suffit d'une ligne de coder pour corriger...

    Quand à getch et getche, sont des fonctions inconnus selon mes bibliothèques.
    C'est quoi ton compilateur? Sous GCC ça marche, conio.h.

    fgetc ne convient à mon problème, car elle retourne un nombre
    fgetc retourne le code ASCII, dans un int mais je ne vois pas le problème...

    Voici un truc vite fait, ça marche mais il doit y avoir plus élégant...
    Code:
    int c;
    do
    {
    	fflush(stdin); /* ça c'est moche mais cela évite que fgetc retourne des caractères qui traînent encore dans le buffer (si quelqu'un entre plusieurs nombres à la fois */
    	c=fgetc(stdin);
    	if(c=='\n')
    		continue;
    	printf("%d %c\n",c,c);
    } while(c!=(int)'f'); /* cast explicite pour bien montrer qu'on est conscient que c soit un int */
    Si tu as besoin d'un nombre 0-9 et non d'un code ASCII la conversion n'est pas compliquée, il suffit de soustraire '0' (<-- en écriture C ceci est un nombre!).

    Bon, je vais voir si je trouve mieux.

    EDIT: Revérifie quand même pour getch(), c'est beaucoup plus propre je trouve...
    Code:
    char c;
    do
    {
    	c=getch();
    	printf("%d %c\n",c,c);
    } while(c!='f');
    Dernière modification par grosmatou75001 ; 13/09/2013 à 18h03.

  7. #6
    grosmatou75001

    Re : Probleme avec fgets

    Apparement sous Visual Studio c'est _getch() (avec un trait devant). Avant d'y passer plus de temps j'attends ta réponse, notamment concernant le compilateur que tu utilises.

  8. #7
    deyni

    Re : Probleme avec fgets

    Bonjour,

    merci de votre réponse. Je sais, il faut faire 2 lectures pour effacer le \n. Mais avec le du char, si on écrit 45, il ne garde que le 5.

    Je ne connaissais pas conio.h

    Je ne comprends pas 2 points dans votre code:
    -le continue
    -la condition d'arrêt
    Et l'utilisateur peut entrer des nombres inférieurs à 10, voire inférieur à 0, je ne sais pas comment faire.
    Voilà ce que j'ai fait, mais c'est sale....


    Code:
    char *c;
    	*c = 'a';
    	while (*c != 'f') {
    			printf("Veuillez saisir un nombre\n");
    			scanf("%s", c);
    			printf("\n");
    	}
    Mais après je dois les stocker dans un tableau de float.....

    edit: Là je suis chez moi, sous windows, je ne sais pas quel est mon compilateur. Sinon, j'utilise linux( compilation en gcc -c....)
    Dernière modification par deyni ; 13/09/2013 à 18h12.
    Deynid'oiseaux partout !! :rire:

  9. #8
    grosmatou75001

    Re : Probleme avec fgets

    Houla, je crois qu'il y a des malentendus de mon côté. Ok, tu veux des NOMBRES, pas des chiffres. Que des entiers ou aussi des réels (à virgule)?

    Voilà ce que j'ai fait, mais c'est sale....
    Oui, tu écris n'importe-où dans la mémoire. Pas bon.

    Mais après je dois les stocker dans un tableau de float.....
    Donc tu veux que l'utilisateur puisse entréer des RÉELS??

    edit: Là je suis chez moi, sous windows, je ne sais pas quel est mon compilateur.
    C'est quoi ton IDE?

    Sinon, j'utilise linux( compilation en gcc -c....)
    Ok, là c'est gcc comme on peut le voir simplement...

  10. #9
    deyni

    Re : Probleme avec fgets

    Oui, il doit y avoir des nombre négatifs, à virgule.....

    Oui c'est sale, mais je déclare un pointeur, et je l'utilise comme un chaine de caractère où est le problème?

    Mon IDE est Geany
    Deynid'oiseaux partout !! :rire:

  11. #10
    deyni

    Re : Probleme avec fgets

    Voilà la suite, mais ça bloque.

    Code:
    int main(){
    	int i;
    	char *c;
    	*c = 'a';
    	float *nombre = NULL;
    	float *plusnombre = NULL;
    	int cpt = 0;
    	while (*c != 'f') {
    			
    			printf("Veuillez saisir un nombre\n");
    			scanf("%s", c);
    			printf("\n");
    			cpt++;
    			plusnombre = (float*)realloc(nombre, sizeof(float)*cpt);
    			
    			if(plusnombre != NULL){
    				nombre = plusnombre;
    				nombre[cpt - 1] = (float)*c;
    			}
    			else {
    				free(nombre);
    				fprintf(stderr, "Erreur a l allocation\n");
    				exit(1);
    			}
    			
    			
    	}
    
    	for(i = 0; i < cpt; i++){
    		printf("%f ", nombre[i]);
    	}
    
    	return 0;
    }
    Je stocke les valeurs dans un tableau, tant que l'utilisateur n’appuie pas sur f.
    Dernière modification par deyni ; 13/09/2013 à 18h32.
    Deynid'oiseaux partout !! :rire:

  12. #11
    grosmatou75001

    Re : Probleme avec fgets

    Du calme! Je termine ce que je fais, je poste une version qui marche, je réponds à l'histoire du pointeur et je regarde le dernier morceau de code. Patience stp.

  13. #12
    deyni

    Re : Probleme avec fgets

    Excusez-moi, je ne voulais pas vous pressez.
    Deynid'oiseaux partout !! :rire:

  14. #13
    grosmatou75001

    Re : Probleme avec fgets

    Tu peux me tutoyer...

    Bon, j'ai sorti le K&R et l'artillerie lourde... Le soucis c'est qu'il faut accepter en même temps des réels valides et la touche f pour terminer. Voilà ce que je propose:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    typedef enum
    {
    	e_nombre_valide,
    	e_fin_lecture,
    	e_erreur
    } etat_t;
    
    etat_t lire(float * const nb)
    {
    	#define SIZE_BUFFER 20
    	char buffer[SIZE_BUFFER]; //ceci est une chaîne de caractères
    	unsigned int i;
    	unsigned int erreur;
    	int nb_virgule;
    
    	//Ici un fflush(stdin) serait bienvenue mais c'est le comportement n'est défini sur stdin...
    
    	fgets(buffer, SIZE_BUFFER, stdin); //lire au maximum SIZE_BUFFER-1 caractères
    	if(strlen(buffer)&&buffer[strlen(buffer)-1]=='\n') //enlever le \n qui nous emmerde (si il y en a un)
    		buffer[strlen(buffer)-1]='\0';
    	if(!strcmp(buffer,"f")) //terminé?
    	{
    		return e_fin_lecture; //ok, on s'en va
    	}
    
    	//vérifier ce qu'a entré l'utilisateur
    	i=0;
    	erreur=0;
    	nb_virgule=0;
    	while((i<SIZE_BUFFER)&&(buffer[i]!='\0')&&(!erreur))
    	{
    		if(buffer[i]=='.')
    			nb_virgule++;
    		if( ! ( (isdigit((int)buffer[i])) || (buffer[i]=='-' && i==0) || ( ( (buffer[i]=='.') && (nb_virgule<=1) && (i) && (i!=strlen(buffer)-1) ) ) ) )
    			erreur=1;
    		i++;
    	}
    
    	//nombre invalide, le signaler
    	if(erreur)
    		return e_erreur;
    
    	//tout va bien, on a vraiment en nombre valide, donc le convertir
    	sscanf(buffer,"%f", nb); //nb est déjà un pointeur, &nb serait FAUX!
    
    	//et signaler que tout va bien
    	return e_nombre_valide;
    }
    
    int main(int argc __attribute__((__unused__)), char** argv __attribute__((__unused__)))
    {
    	etat_t etat;
    	float f;
    
    	do
    	{
    		etat=lire(&f);
    		if(etat==e_erreur)
    			printf("vous rentrez n'importe quoi!!\n");
    		else if(etat==e_nombre_valide)
    			printf("ok, nombre: %.2f\n",f);
    	} while(etat!=e_fin_lecture);
    
    	return 0;
    
    }
    Il reste un défaut que je n'arrive pas à enlever: Si l'utilisateur rentre plus de caractères que SIZE_BUFFER genre "fffffffffffffffffffffffffffff ffffffffffffffffffffffff" la boucle va tourner plusieurs fois en ne lisant que SIZE_BUFFER caractères à la fois et risque donc de produire des bêtises. La solution évidente est fflush(stdin) mais le K&R m'enseigne que cela a un comportement indéfini... (Bon, sous GCC ça marche comme on le pense mais faisons les choses proprement.) J'ai essayé divers trucs mais rien ne marche correctement. Il faut donc faire confiance à l'utilisateur de ne pas "innonder" le programme de caractères et choisir un SIZE_BUFFER pas trop petit. A part celà le programme marche plutôt bien et ne valide que les entiers vraiments valides. A toi de me dire si il y a encore des erreurs.

  15. #14
    grosmatou75001

    Re : Probleme avec fgets

    Oui c'est sale, mais je déclare un pointeur, et je l'utilise comme un chaine de caractère où est le problème?
    En faisant ceci
    Code:
    char *c;
    tu définis un pointeur. Comme tu n'initialise pas il va pointer vers une adresse aléatoire. Et là
    Code:
    *c = 'a';
    tu écris à cette adresse, donc quelque part en mémoire, ce qui peut te coûter cher. Essaye donc
    Code:
    char *c=NULL;
    *c='a';
    et tu comprendra... Permettre ce genre de trucs c'est une des grandes critiques qu'on peut faire au language C mais c'est HS ici.

    Mon IDE est Geany
    Ok, je ne connais pas, le compilateur peut-être GCC ou autre chose. Peu importe, mon dernier programme est "standard-compilant" donc marche partout (j'espère...).

  16. #15
    grosmatou75001

    Re : Probleme avec fgets

    Et voilà ce que je propose pour le problème en soi, j'ai simplement adapté ton code du message #10 à ma nouvelle fonction.

    Code:
    int main(int argc __attribute__((__unused__)), char** argv __attribute__((__unused__)))
    {
    	etat_t etat;
    	float f;
    
    	int i;
    	float *nombre = NULL;
    	float *plusnombre = NULL;
    	int cpt = 0;
    
    	do
    	{
    		etat=lire(&f);
    		if(etat==e_erreur)
    		{
    			printf("vous rentrez n'importe quoi!!\n");
    			continue;
    		}
    		else if(etat==e_nombre_valide)
    		{
    			cpt++;
    			plusnombre = (float*)realloc(nombre, sizeof(float)*cpt);
    
    			if(plusnombre != NULL){
    				nombre = plusnombre;
    				nombre[cpt - 1] = f;
    			}
    			else {
    				free(nombre);
    				fprintf(stderr, "Erreur a l allocation\n");
    				exit(1);
    			}
    		}
    
    	} while(etat!=e_fin_lecture);
    
    	for(i=0;i<cpt;i++)
    		printf("nombre n %d = %.2f\n",i,nombre[i]);
    
    	free(nombre);
    
    	return 0;
    }
    Code:
    if(questions)
    	poser(questions);

  17. #16
    grosmatou75001

    Re : Probleme avec fgets

    Grmbl!

    Citation Envoyé par grosmatou75001 Voir le message
    A part celà le programme marche plutôt bien et ne valide que les entiers vraiments valides.
    Je voulais dire des RÉELS!

  18. #17
    grosmatou75001

    Re : Probleme avec fgets

    Ca serait quand même bien d'avoir un petit retour de la part de deyni...

Discussions similaires

  1. fgets : stocker dans des variables différentes à la ceuleuleu
    Par AmigaOS dans le forum Programmation et langages, Algorithmique
    Réponses: 5
    Dernier message: 02/03/2013, 21h47
  2. Réponses: 0
    Dernier message: 26/04/2011, 21h25
  3. [C] Utilisation de fgets
    Par invitec13ffb79 dans le forum Logiciel - Software - Open Source
    Réponses: 19
    Dernier message: 25/07/2009, 20h24
  4. Réponses: 10
    Dernier message: 22/03/2009, 10h34
  5. Langage C / fgets
    Par invitee5fedd72 dans le forum Logiciel - Software - Open Source
    Réponses: 5
    Dernier message: 13/05/2007, 22h41