Langage C, fgets dans une fonction.

Fermé
Pineau - 11 avril 2008 à 11:51
 anonyme0 - 21 avril 2008 à 19:59
Bonjour,

Je reviens vers vous pour une question concernant cette fois ci la fonction "fgets" servant à alimenter un tableau en char.

Dans mon cas précis, j'ai un tableau de cette forme : char Tech[250][20]

C'est donc un tableau où par ligne je peut entrer une chaine de 20 caractères au maximum.

Lorsque j'utilise ce tableau dans une boucle for pour l'alimentation du tableau je n'ai pas de soucis. Je procède de cette manière :

main()
{
      char Tech[250][20];
      int i;
      
      for (i=0; i<=250; i++)
      {
      printf("Nom de l'intervenant : ");
      fgets(Tech[i], 20, stdin);
      printf("\n\n%s", Tech[i]);
      }
      
      getch();
}


Ici je rentre le nom d'un technicien dans les lignes du tableau et le programme mes les affiche au fur et à mesure de la boucle.

Le truc c'est qu'il faut que j'arrive a l'intégrer a ma fonction que je vous avez déjà présentée. Et je ne comprend pas pourquoi, le compilateur me signale une erreur au niveau de ma ligne : fgets...

Voila mon code de la fonction :

void initableau(int Inter[], int Prio[], int *i, char Tech[][])
{
     int z=*i;
     printf("Saisir -1 pour sortir.\n\n");
     do 
             { 
               printf("Numero d intervention : ");
               scanf("%d", &Inter[z]);
       
               if (Inter[z]!=-1)
                  {
                  printf("Indice de priorite : ");
                  scanf("%d", &Prio[z]);
                  printf("Nom de l'intervenant : ");
                  fgets(Tech[z], 20, stdin);   /* on me signale ici un probleme*/
                  printf("\n\n\n");
                  }
               z++;
              }
     while (Inter[z-1]!= -1);
     
     *i=z;
     return ;       
}


Si quelqu'un peut m'expliquer pourquoi il y a un soucis ca me serait d'une aide précieuse.

Je vous remercie d'avance, et vous souhaite une bonne journée.

Cordialement.

Pineau.
A voir également:

12 réponses

Je relance le sujet car je n'ai recu aucune réponse.

J'ai entendu dire par un ami que la solution du tableau à plusieurs colonnes n'était pas la meilleure. Il m'a parler vite fait de tableau de pointeurs utilisant les fonction "argc" et "argv[]" mais je n'ai franchement pas compris tout l'interet de la chose.

Si quelqu'un pouvait m'éclairer sur ce point ca me serait vraiment tres utile.

Merci d'avance et a bientot.
0
bonjour,

Ci dessous un exemple de passage d'un tableau de char à une fonction, en espérant que cal pourra t'éclairer.
#include <stdio.h>
#include <stdlib.h>


void initableau(int it , char T[][]); /*fonction prototype*/

void main()
{
      char Tech[5][20];
      int i;

      for (i=0; i<5; i++)
      {
      initableau(i, Tech); /*appel fonction*/
      printf("%s", Tech[i]); /*verification que la tableau à bien ete modifié*/
      }
      
      getch();
return;
}

void initableau(int it, char T[][20])     
{
     printf("\n\nNom de l'intervenant : ");
     gets(T[it]);
     return ;       
}
0
La meme fonction avac fgets()
void initableau(int it, char T[][20])     
{
     printf("\n\nNom de l'intervenant : ");
     fgets(T[it],20,stdin);
     return ;       
}


A+.
0
J'ai bien peur de ne pas saisir comment cela fonctionne.

Pourquoi avoir fait 2 fonction "initableau" ? Pourquoi l'une decrit tech[][] et l'autre Tech[][20] ?

Il me semblait aussi que l'on m'avait dit qu'il fallait mettre un pointeur et non une fontcion dans la description des variables...

Desole mais je ne comprends pas ce que tu as voulu me montrer.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Re,

la ligne
void initableau(int it , char T[][]); /*fonction prototype*/

est juste une fonction prototype qui indique au compilateur comment interpreter les arguments passés à la fonction, parce que la fonction est definie apres main().

Dans la définition de la fonction initableau, le compilateur à besoin de connaitre la taille d'une ligne du tableau, afin de calculer le decalage par rapport à l'origine en fonction de l'index, d'où
void initableau(int it, char T[][20])


S'agissant de tableau de char, le compilateur sait qu'il a affaire a un pointeur et donc il ne faut pas mette *tech,
pour preuve, si on execute le petit programme que je t'ai transmis, on voit bien que la fonction a bien modifié le tableau Tech, c'est donc que ce tableau lui a été passé par référence (ou par adresse).

Salut.
0
Bon je vais récapituler ...


le truc c'est que je voudrais insserrer dans ma fonction deja existante, un tableau char.


void initableau(int Inter[], int Prio[], int *i)
{
     int z=*i, it;
     printf("Saisir -1 pour sortir.\n\n");
     do 
             { 
               printf("Numero d intervention : ");
               scanf("%d", &Inter[z]);
       
               if (Inter[z]!=-1)
                  {
                  printf("Indice de priorite : ");
                  scanf("%d", &Prio[z]);
                  intervenant(it, Tech); /* <==== ici je veux que ca puisse me demander le nom de l'intervenant pour l'intervention */
                  printf("\n\n\n");
                  }
               z++;
              }
     while (Inter[z-1]!= -1);
     
     *i=z;
     return ;       
}


Jai essayer comme tu me le décris ci dessus mais je n'y arrive pas :'(
J'ai tenté de mettre une fonction protocole comme tu me le dis mais je ne comprend vraiment pas le but. Mon but est juste de pouvoir saisir :

Numéro de l'intervention : réponse
Indice de priorité : réponse
Nom de l'intervenant : réponse

Avec ce que tu m'as expliquer le programme compile mais saute la question du nom de l'intervenant.
Surement ai-je fait une boulette mais je ne vois pas comment inscrire ta fonction dans la mienne.

J'ai bien essayer de faire carrément un autre void et de l'apeler dans ma fonction, j'ai tenté de mettre la fonction protocole avant ma fonction, l'appeler dedans puis la decrire apres mais rien ne marche.

Qu'est ce qui ne vas pas dans mon code ?


void intervenant(int it, char Tech[][]);

void initableau(int Inter[], int Prio[], int *i)
{
     char Tech[250][20];
     int z=*i, it;
     printf("Saisir -1 pour sortir.\n\n");
     do 
             { 
               printf("Numero d intervention : ");
               scanf("%d", &Inter[z]);
       
               if (Inter[z]!=-1)
                  {
                  printf("Indice de priorite : ");
                  scanf("%d", &Prio[z]);
                  intervenant(it, Tech);
                  /*printf("Nom de l'intervenant : ");
                  fgets(Tech[z],20,stdin);*/
                  printf("\n\n\n");
                  }
               z++;
              }
     while (Inter[z-1]!= -1);
     
     for (z=0; z<6; z++)
         {
               printf("%s", Tech[z]);
         }
     
     *i=z;
     return ;       
}

void intervenant(int it, char Tech[][20])     
{
     printf("Nom de l'intervenant : ");
     fgets(Tech[it],20,stdin);
     return ;       
}


C'est pourtant comme ca que tu me l'a ecris non ?

Merci d'avance.
0
Ok merci bien je vais essayer ca de suite.
0
Re,

printf("Indice de priorite : ");
scanf("%d", &Prio[z]);
intervenant(it, Tech);/*<========== it n'est pas initialisé*/

la variable it est l'indice du tableau ou sera insré la chaine entrée avec fgets()

dans ton prog je cois que c'est la variable z
assure toi que la valeur de z est correcte avant l'appel à la fonction.

ecrire

fprintf("indice tableau : %d\n",z);/*<==========verifier l'indice*/
getch();
intervenant(z, Tech);

apres le debogage tu pourras supprimer ces deux lignes

Il y a quand meme un problème, le tableau char Tech[250][20] est déclaré dans la fonction initableau.
Il ne sera pas accessible dans main(). Il faudrait bien analyser la portée de tes variables. Si le tableau Tech doit etre utilisé ailleurs que dans la fonction initableau, ce que je crois, il doit etre déclaré dans main() et etre passé en argument aux fonctions, ou encore etre déclaré en dehors de toutes fonctions en début de programme. Il sera alors global à toutes les fonctions et sera accesible partout, sans le passer en argument.
Est ce que tu vois ce que je veux dire?

A+.
0
Oui je comprend ce que tu veux dire ;)

J'ai donc fait un printf pour connaitrela valeur de z avant l'appel de ma fonction. Le truc c'est que l'indice est bon mais que ca saute toujours la question :s ca l'affiche mais ca passe directement a la suite du programme (c'est a dire qu'il me redemande un nouveau n° d'intervetion, ce qui est tout a fait normal).

Donc finalement le programme ne me demande jamais de remplir le tableau en char et c'est ce qui m'ennui ... ^^
0
Normalement, le prog doit demander
1) le n° d'intervention Inter[z]
2) si Inter[z] != -1 : l'Indice de priorite Prio[z] et Nom de l'intervenant Tech[z]

est ce que tu arrive a saisir ces valeur?

pour verifier que ça s'est bien passé mets printf("%s", Tech[z]); aprés l'appel a la fonction

intervenant(z, Tech);
printf("%s", Tech[z]);

Si tu as du mal, envoie moi ton code complet, je tenterai de le corriger.

A+.
0
Justement non ^^

Ca me demande bien l'indice mais pas le nom.
Donc meme en mettant un printf je ne verrais rien vu que je n'ai rien saisi.


char Tech[250][20];

/****************************************Alimentation du tableau*****************************************/

void intervenant(int it);

void initableau(int Inter[], int Prio[], int *i)
{
     
     int z=*i;
     printf("Saisir -1 pour sortir.\n\n");
     do 
             { 
               printf("Numero d intervention : ");
               scanf("%d", &Inter[z]);
       
               if (Inter[z]!=-1)
                  {
                  printf("Indice de priorite : ");
                  scanf("%d", &Prio[z]);
                  printf("%d", z);
                  getch();
                  intervenant(z);
                  /*printf("Nom de l'intervenant : ");
                  fgets(Tech[z],20,stdin);*/
                  printf("\n\n\n");
                  }
               z++;
              }
     while (Inter[z-1]!= -1);
     
     for (z=0; z<6; z++)
         {
               printf("%s", Tech[z]);
         }
     
     *i=z;
     return ;       
}

void intervenant(int z)     
{
     printf("Nom de l'intervenant : ");
     fgets(Tech[z],20,stdin);
     return ;       
}


J'ai essayé d'appliquer ce que tu m'as dit en mettant l'initialisation de Tech en debut de programme et en l'enlevant des argument mais toujours rien :(

mon main est fait ainsi :

main ()
{
     int Inter[250], Prio[250], i=0, k, var, tamp, choix;
     char Tech[250][20];
     BIENVENUE;
     
     i=0;
 
     initableau(Inter, Prio, &i);
     var=i-2;
     tritableau(Inter, Prio, &i, &var);
     affichage(Inter, Prio, &i, &var);
getch();
}


Si ca peut te servir a comprendre mon erreur :)

Merci encore !
0
Bonjour,

Je t'ai fait 2 versions, une avec des variables tableaux globales, et l'autre avec des variables tableaux locales dans main().
Ce qui diffère, c'est l'appel des fonctions et l'accès aux tableaux.

J'ai mis en commentaires les fonctions BIENVENUE, tritableau et affichage.

J'ai aussi rajouté la fonction fflush(stdin) pour vider le Buffer du clavier, sinon la fonction fgets() qui suit ne marche pas bien.

La fonction system("cls") sert a effacer l'ecran, si elle n'est pas supporté par ton système, il faut l'enlever.

J'ai compilé et exécuté les deux versions avec Borland C++ 3.0

Version avec variables globales:
#include <stdio.h>
#include <stdlib.h>

/*variables globales*/
int Inter[250], Prio[250];
char Tech[250][20];

/*fonction prototype*/
void initableau(int *i);

void main ()
{
     int i=0, k, var, tamp, choix;
     /*BIENVENUE;*/
     system("cls");     
     i=0;
 
     initableau(&i);
     /*verification des saisies*/
     for (k=0;k<i-1;k++)
     {   printf("\nInter[%d]=%d ; Prio[%d]=%d ; Tech[%d]=%s",
                 k, Inter[k], k, Prio[k], k, Tech[k]);
     }
     var=i-2;
     /*tritableau(Inter, Prio, &i, &var);*/
     /*affichage(Inter, Prio, &i, &var);*/
getch();
}


/*****************Alimentation du tableau**************************/

void initableau(int *i)
{
     
     int z=*i;                                                     
     printf("Saisir -1 pour sortir.\n\n");
     do 
             { 
               printf("Numero d intervention : ");
               scanf("%d", &Inter[z]);
       
               if (Inter[z]!=-1)
                  {
                  printf("Indice de priorite : ");
                  scanf("%d", &Prio[z]);
                  fflush(stdin);
                  printf("Nom de l'intervenant : ");
                  fgets(Tech[z],20,stdin);
                  /*printf("%s", Tech[z]);*/ 
                  printf("\n\n\n");
                  }
               z++;
              }
     while (Inter[z-1]!= -1);
     
     *i=z;

     return ;       
}

Version avec Variables locales:
#include <stdio.h>
#include <stdlib.h>

/*fonction prototype*/
void initableau(int Inter[], int Prio[], int *i, char Tech[][20]);

void main ()
{
     /*variables locales*/
     int Inter[250], Prio[250], i=0, k, var, tamp, choix;
     char Tech[250][20];
     /*BIENVENUE;*/
     
     i=0;
 
     initableau(Inter, Prio, &i, Tech);
     /*verification des saisies*/
     for (var=0;var<i-1;var++)
     {   printf("\nInter[%d]=%d ; Prio[%d]=%d ; Tech[%d]=%s",
                 var, Inter[var], var, Prio[var], var, Tech[var]);
     }
     var=i-2;
     /*tritableau(Inter, Prio, &i, &var);*/
     /*affichage(Inter, Prio, &i, &var);*/
getch();
}


/*****************Alimentation du tableau**************************/

void initableau(int Inter[], int Prio[], int *i, char Tech[][20])
{
     
     int z=*i;                                                     
     printf("Saisir -1 pour sortir.\n\n");
     do 
             { 
               printf("Numero d intervention : ");
               scanf("%d", &Inter[z]);
       
               if (Inter[z]!=-1)
                  {
                  printf("Indice de priorite : ");
                  scanf("%d", &Prio[z]);
                  fflush(stdin);
                  printf("Nom de l'intervenant : ");
                  fgets(Tech[z],20,stdin);
                  /*printf("%s", Tech[z]);*/ 
                  printf("\n\n\n");
                  }
               z++;
              }
     while (Inter[z-1]!= -1);
     
     *i=z;

     return ;       
}
0
Puis je me permettre de te demander une derniere petite chose ?

Comme tu l'as vu sur mon code, je fais un tri apres avoir entré les renseignements dans mon tab leau.
Pour se faire, je dois stocker temporairement ma chaine de caractèere dans un autre tableau.

Comment t'y pendrais tu ?

J'ai essayé en faisant juste un utableau d'une colonne : char Chartamp[21];

Mais je ne crain que ca créer un bug.

Chartamp[0]=Tech[z][20];
Tech[z][20]=Tech[k][20];
Tech[k][20]=chartamp[0];


De cette maniere ca ne me prend que la premiere lettre du nom saisi ...

Si tu as une idée ^^

Merci d'avance.
0
Bonjour,


MERCI !!! t'es genial ca marche ^^

Je pense que le probleme venait du fait que mon buffer n'etait pas vide, d'ou l'impossibilité d'ecrire un nom.
Grace a : "fflush(stdin);" ca marche maintenant !

Merci enormément.


Desole de t'avoir déranger si longtemps pour ca !

Merci mille fois :)
0
Bonjour,

Avec un peu de retard, je répond à ta question.

Tu veux faire un tri par ordre alphabétique je suppose. Il y a plusieurs méthodes de tri. Pour comparer des chaines il y a la fonction strcmpi() qui est très pratique, elle ignore les minuscules et les majuscules. Sinon il y a la classique strcmp().

Donc il suffit de détreminer le mode de comparaison et appliquer une méthode de tri.

A+.
0
Non non du tout ^^

En fait, je dois trier par ordre decroissant des indices de priorité. Les intervenant doivent rester sur la meme intervention.
Donc le truc c'est que j'arrive a trier les interventions par ordre decroissant des indices, mais je n'arrive pas a mettre les noms des intervenant un par un dans un tampon pour les re mettre ensuite dans leur tableau initiale mais sous le meme ordre que le tri des indices.

J'ai mis un post un peu au dessus ou je te montre la facon dont j'ai essayé de trier les chaines de caracteres mais ca ne fonctionne pas.

Si tu pouvvais m'expliquer ceci ca me serait tres utile.

Merci
0
Bonjour,

Je pense que tu devrait faire un tableau Index trié par ordre décroissant des indices de priorité, qui mémorise l'ancienne position de chaque indice de priorité avant le tri. Ensuite c'est facile de reconstituer chaque tableau.

Exemple:
Position         Numéro            Indice Prio       Intervenant    
Actuelle       Intervention
-----------------------------------------------------------------
   0                1                    5              Toto
   1                2                    9              Titi
   2                4                    6              Tata
   3                6                    1              Tutu

   
Tableau Index trié suivant Indice Prio

Nouvelle         Ancienne
Postion          Position          (Indice Prio)
-------------------------------------------------
   0                1                   (9)
   1                2                   (6)
   2                0                   (5)
   3                3                   (1)

Ensuite recontruire le Tech[] et Inter[z]
strcpy(TechTemp,Tech[NP]);//Sauvegarger la chaine
strcpy(Tech[NP],Tech{AP]);//Remplacer la chaine
strcpy(Tech[AP],TechTemp);//Copie de la chaine sauvegargée à l'endroit libéré

Pour NP=0 -> AP=1
TechTemp=Tech[0]="Toto"
Tech[0]=Tech[1]="Titi"
Tech[1]=TechTemp="Toto"

Donc on a bien échangé Titi et Toto. Faire de meme pour Inter[]

Une autre méthode serait de déplacer Tech[] et Inter[] en meme temps que Prio[].
je crois que c'est ce que tu as essayé de faire, mais il aurait fallu l'ecrire de cette façon
strcpy(Chartamp,Tech[z]);
strcpy(Tech[z],Tech[k]);
strcpy(Tech[k],chartamp);

Salut.
0