IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Fonction de saisie qui retourne plusieurs paramètres


Sujet :

C

  1. #1
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut Fonction de saisie qui retourne plusieurs paramètres
    Bonjour,

    J'ai developpé une petite fonction qui effectue effectue une saisie dans une variable. Celle-ci ne doit pas faire plus de 20 caractères.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    char* saisie(){
    char* buf;
    char* c;
    c=(char*)malloc(1*sizeof(char));
    int i=0;
     
    while(fgets(c,2,stdin)){
    	if(strncmp(c,"\n",1)==0) break;
    	buf=(char*)realloc(buf,(i+1)*sizeof(char));
    	if(i==0) strcpy(buf,c);
    	else strcat(buf,c);
    	i++;
    }
     
    if(i<21){
    	buf=(char*)realloc(buf,(i+1)*sizeof(char));
    	buf[i]='\0';
    	return buf;
    }else{
    	free(buf);
    	return "\0";
    }
    }
    Mais je voudrais que ma fonction retourne le résultat de la saisie dans une variable buf qui serait le premier argument, et qu'elle retourne 0 si la variable compte moins de 20 caractères ou 1 si celle-ci a due être tronquée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    int saisie(char* buf){
        char* c;
    	c=(char*)malloc(1*sizeof(char));
    	int i=0;
     
    	while(fgets(c,2,stdin)){
    		if(strncmp(c,"\n",1)==0) break;
    		buf=(char*)realloc(buf,(i+1)*sizeof(char));
    		if(i==0) strcpy(buf,c);
    		else strcat(buf,c);
    		i++;
    	}
     
    	if(i<21){
    		buf=(char*)realloc(buf,(i+1)*sizeof(char));
    		buf[i]='\0';
    		return 0;
    	}else{
    		buf=(char*)realloc(buf,21*sizeof(char));
    		buf[20]='\0';
    		return 1;
    	}
    }
    Et l'appeler ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int main(void){
       char* buf=NULL;
       int err;
     
       err=saisie(buf);
    }
    Mais cela ne fonctionne pas. Je crois qu'il faudrait que je passe en argument un pointeur sur l'adresse de buf ... mais j'ai du mal.

  2. #2
    Membre éprouvé
    Avatar de Freed0
    Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    635
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Points : 953
    Points
    953
    Par défaut
    Salut,

    Pense à soigner la présentation de ton code

    Sinon, je ne comprend pas pourquoi tu utilise fgets pour effectuer la saisie d'un seul caractère... fgets lit une ligne entière.
    Tu devrais plutôt utiliser fgetc je pense.

    Sinon, pas besoin de caster le malloc/realloc/calloc.
    sizeof (char) est inutile aussi... ça vaut 1.

    Le paramètre de ta fonction étant déjà un pointeur (char *), ça devrait être OK de ce coté là

    Allez hop au travail

  3. #3
    Membre du Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Août 2007
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Août 2007
    Messages : 52
    Points : 53
    Points
    53
    Par défaut
    En fait il faut passer à ta fonction un pointeur sur le tableau et non le tableau car les modifications des paramètres sont local

    int saisie(char** buf)
    {
    ici utiliser *buf en non buf
    }

    et l'appeler ainsi saisie(&buf);

  4. #4
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    Merci, je vais modifier.

  5. #5
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    Merci Mizar,
    En faisant ainsi dans ma fonction, comment dois je faire mes allocations ?
    Sur buf, *buf ?

    edit : je viens d'ouvrir les yeux et de relire ton message désolé.

  6. #6
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    C'est encore moi,

    Freed0, j'utilise fgets car j'ai du mal avec fgetc, cette fonction retourne du unsigned char. Comment faire ensuite avec l'utilisation de strcpy et strcat ?

    Mizar, j'ai toujours un problème au niveau de *buf[i]='\0'. Sinon le reste à l'air de passer

    Merci pour votre aide.

  7. #7
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par PKO06
    J'ai developpé une petite fonction qui effectue effectue une saisie dans une variable. Celle-ci ne doit pas faire plus de 20 caractères.

    Mais cela ne fonctionne pas. Je crois qu'il faudrait que je passe en argument un pointeur sur l'adresse de buf ... mais j'ai du mal.
    Je conseille cet interface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *saisie (size_t max, int *p_err)
    Ca s'utilise ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
       int err;
       char *chaine = saisie (20, &err);
       if (chaine != NULL)
       {
          if (err)
          {
              printf ("Attention, saisie tronquee\n");
          }
     
          /* usage */
     
          free (chaine);
       }

  8. #8
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    Merci Emmanuel,

    Tu viens de répondre à une question que je n'avais même pas posée, si ça c'est pas fort.
    C'est bien plus propre comme ça, je m'y mets.


  9. #9
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    Après tous vos conseils, ma fonction ressemble maintenant à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    char* saisie(size_t max,int *p_err){
        char *c=NULL;
    	char* buf=NULL;
    	size_t i=0;
     
    	c=malloc(1);
    	while(fgets(c,2,stdin)){
    		if(strncmp(c,"\n",1)==0) 
    			break;
    		buf=realloc(buf,(i+1));
    		if(i==0) 
    			strcpy(buf,c);
    		else 
    			strcat(buf,c);
    		i++;
    	}
     
    	if(i<max+1){
    		buf=realloc(buf,(i+1));
    		buf[i]='\0';
    		*p_err=0;
    	}else{
    		buf=realloc(buf,21);
    		buf[20]='\0';
    		*p_err=1;
    	}
    	return buf;
    }
    Mizar75 m'a conseillé d'utiliser fgetc mais je n'arrive pas à maitriser cette fonction. Est ce que celà est un problème et pourra t'on me le reprocher ?

    Est ce qu'il n'y a pas de problèmes dans mes reallocations, je n'utilise pas de tampon.

    Cela fonctionnant tout de même je place une balise [RESOLU]

    Merci

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par PKO06
    Après tous vos conseils, ma fonction ressemble maintenant à ça :

    Mizar75 m'a conseillé d'utiliser fgetc mais je n'arrive pas à maitriser cette fonction. Est ce que celà est un problème et pourra t'on me le reprocher ?

    Est ce qu'il n'y a pas de problèmes dans mes reallocations, je n'utilise pas de tampon.
    C'est dix mille fois trop compliqué.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
     
    char *saisie (size_t max, int *p_err)
    {
       int err = 0;
       /* allouer le bloc avec un espace pour le \n et le 0 final */
       char *buf = malloc (max + 2);
       if (buf != NULL)
       {
          /* lire le flux entrant */
          if (fgets (buf, max + 2, stdin) != NULL)
          {
             /* chercher le \n */
             char *p = strchr (buf, '\n');
             if (p != NULL)
             {
                /* trouve : suppression */
                *p = 0;
             }
             else
             {
                /* sinon : indication de troncature */
                err = 1;
                buf[max] = 0; /* EDIT */
             }
          }
          else
          {
             /* pas de saisie */
             free (buf), buf = NULL;
          }
       }
       else
       {
          err = 1;
       }
     
       /* retourner l'erreur */
       if (p_err != NULL)
       {
          *p_err = err;
       }
     
       /* retourner l'adresse du bloc alloue */
       return buf;
    }
     
    int main (void)
    {
       int err;
       char *chaine = saisie (20, &err);
       if (chaine != NULL)
       {
          if (err)
          {
             printf ("Attention, saisie tronquee\n");
          }
     
          /* usage */
          printf ("saisie = '%s'\n", chaine);
     
          free (chaine);
       }
     
       return 0;
    }

  11. #11
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    Beaucoup plus limpide !
    Mais, malgré l'allocation de max+2, est ce que la chaine saisie, si elle ne fait que 10 caractères, ne prendra que 10 octets en mémoires ?

    En d'autres termes, suivant mon petit raisonnement, ne faut il pas allouer 11 octets pour buf ?

    edit : J'aurais mieux fait de tester avant. C'est impeccable, très beau code !
    Il faut juste faire une petite modification pour que la chaine renvoyée, si elle est tronquée, ne comporte que 20 caractères (pour l'instant il y a bien l'indication de chaine tronquée au dessus de 20 caractères mais elle en comporte 21).

    Merci beaucoup Emmanuel.

  12. #12
    Membre du Club Avatar de PKO06
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    91
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 91
    Points : 65
    Points
    65
    Par défaut
    Je me suis donc permis de rajouter une ligne au niveau de l'indication de troncage pour éviter que buf ne contiennent 21 caractères.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    char *saisie (size_t max, int *p_err)
    {
       int err = 0;
       /* allouer le bloc avec un espace pour le \n et le 0 final */
       char *buf = malloc (max + 2);
       if (buf != NULL)
       {
          /* lire le flux entrant */
          if (fgets (buf, max + 2, stdin) != NULL)
          {
             /* chercher le \n */
             char *p = strchr (buf, '\n');
     
             if (p != NULL)
             {
                /* trouve : suppression */
                *p = 0;
             }
             else
             {
                /* sinon : indication de troncage */
    	     buf[max]='\0';
                err = 1;
             }
          }
          else
          {
             /* pas de saisie */
             free (buf), buf = NULL;
          }
       }
       else
       {
          err = 1;
       }
     
       /* retourner l'erreur */
       if (p_err != NULL)
       {
          *p_err = err;
       }
     
       /* retourner l'adresse du bloc alloue */
       return buf;
    }
    Mais c'est moins joli

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par PKO06
    Il faut juste faire une petite modification pour que la chaine renvoyée, si elle est tronquée, ne comporte que 20 caractères (pour l'instant il y a bien l'indication de chaine tronquée au dessus de 20 caractères mais elle en comporte 21).
    OK. J'ai fait la modif dans le code. Ca donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    012345678901234567890
    Attention, saisie tronquee
    saisie = '01234567890123456789'
     
    Press ENTER to continue.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonction qui retourne plusieurs valeurs !
    Par casafa dans le forum C++
    Réponses: 20
    Dernier message: 23/04/2014, 17h56
  2. Fonction d'une DLL qui retourne plusieur valeur
    Par vtk37 dans le forum Débuter
    Réponses: 9
    Dernier message: 27/05/2009, 11h01
  3. Fonction qui retourne plusieurs paramètres
    Par diam's dans le forum Langage
    Réponses: 3
    Dernier message: 03/02/2006, 21h11
  4. [PL/SQL] Fonction qui retourne plusieurs valeurs
    Par Loko dans le forum Oracle
    Réponses: 2
    Dernier message: 07/12/2004, 10h43
  5. Réponses: 14
    Dernier message: 09/04/2004, 14h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo