demande petite aide pour newbi du C :)

demande petite aide pour newbi du C :) - C - Programmation

Marsh Posté le 05-09-2005 à 14:45:27    

Bonjour je suis en formation de programmeur micro. Et comme je débute, j'ai un peu du mal.
 
Voici l'énoncé de mon exercice :
 

Citation :


Ecrire une fonction qui permet d'entrer des caractères du clavier dans un tableau t, y compris espaces et tabulations, ce que ne peut faire l'instruction scanf("%s",t);. L'entrée des caractères se termine par un retour-chariot. La fonction sera définie comme suit :
 

Code :
  1. lecture(t)
  2. char *t;
  3. {
  4. ...à écrire...
  5. }


 
On prendra le programme principal suivant pour tester la fonction.
 

Code :
  1. #include <stdio.h>
  2. main()
  3. { char t[100];
  4. lecture (t);
  5. printf("%s",t);
  6. }




 
Voici le code que j'ai commencé :
 
#include <stdio.h>
 

Code :
  1. int main(void) {
  2. char t[100];
  3. lecture(t);
  4. printf("%s\n",t);
  5. printf("\n" );
  6. return 0;
  7. }
  8. void lecture(t) {
  9. char *t;
  10. printf("Entrez des caractères : \r" );
  11. gets(*t);
  12. }


 
je sais qu'il est bourré de conneries. Quelqu'un peut t'il m'aider ou me filer le code pour que je puisse comprendre avec mon cours svp.
Un grand merci d'avance.

Reply

Marsh Posté le 05-09-2005 à 14:45:27   

Reply

Marsh Posté le 05-09-2005 à 14:52:49    

1. Ne jamais, jamais, jamais utiliser gets(). C'est un bug ambulant cette fonction, et elle est dépréciée depuis quelques années (elle n'est encore là que pour des raisons de compatibilité). Utiliser fgets() à la place.
 
2. Définition de la fonction lecture() fausse, il faut donner un type à l'argument "t" qu'elle reçoit. Ne pas redéfinir la variable t dans la fonction non plus, relis l'énoncé, tu as fait une erreur. Enoncé qui d'ailleurs est obsolète, car on ne définit plus les fonctions comme ça depuis longtemps:

void lecture(char *t)  {
...
}


 
 
Relis ton cours, recherche des tutoriaux, et réessaie.
 
PS : on ne donne pas de programme tout fait sur ce forum, encore moins de réponses à des exercices, juste de l'aide, des exemples, ou des morceaux précis.
 
EDIT : plein d'edit, a y est c'est fini, désolé j'avais mal lu le sujet.  [:elmoricq]


Message édité par Elmoricq le 05-09-2005 à 15:07:25
Reply

Marsh Posté le 05-09-2005 à 15:40:45    

nDeXok a écrit :

je suis en formation de programmeur micro.
Voici l'énoncé de mon exercice :

Citation :


Ecrire une fonction qui permet d'entrer des caractères du clavier dans un tableau t, y compris espaces et tabulations, ce que ne peut faire l'instruction scanf("%s",t);. L'entrée des caractères se termine par un retour-chariot. La fonction sera définie comme suit :

Code :
  1. lecture(t)
  2. char *t;
  3. {
  4. ...à écrire...
  5. }





Une formation qui propose d'écrire une fonction de saisie aussi mal prototypée que gets() [1] n'est pas sérieuse. Change d'urgence d'organisme et fait toi rembourser.
 
Donne le nom de l'organisme, qu'on le mette en liste noire.
 
----------------------
[1] et en plus dans un style obsolète depuis 1989


Message édité par Emmanuel Delahaye le 05-09-2005 à 15:43:24

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 05-09-2005 à 15:56:28    

Je fais ça chez Educatel... vous avez un autre organisme à me conseiller en formations à distance ? :/


Message édité par nDeXok le 05-09-2005 à 16:00:32
Reply

Marsh Posté le 05-09-2005 à 15:59:46    


Eh beh !
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 06-09-2005 à 10:45:47    

Emmanuel Delahaye a écrit :

Une formation qui propose d'écrire une fonction de saisie aussi mal prototypée que gets() [1] n'est pas sérieuse. Change d'urgence d'organisme et fait toi rembourser.
[1] et en plus dans un style obsolète depuis 1989


C'est assez facile comme conseil. En général, il est difficile de se faire rembourser un truc commencé. Et va donc prouver que cette formation est nulle. Le moins qu'on puisse faire c'est d'essayer de limiter les dégats
 

nDeXok a écrit :

Voici le code que j'ai commencé :

Code :
  1. #include <stdio.h>
  2. int main(void) {
  3. char t[100];
  4. lecture(t);
  5. printf("%s\n",t);
  6. printf("\n" );
  7. return 0;
  8. }
  9. void lecture(t) {
  10. char *t;
  11. printf("Entrez des caractères : \r" );
  12. gets(*t);
  13. }




Voici les soucis et erreurs (déjà dit par Elmoricq)
1) on ne redéfinit pas le paramètre comme si c'était une nouvelle variable. Il faut seulement le déclarer entre le nom de la fonction et l'accolade ouvrante (relis ton cours sur la syntaxe des fonctions)

Code :
  1. void lecture(t)
  2. char *t;
  3. {
  4.   ...
  5. }


 
2) ce genre de syntaxe (on liste les paramètres puis on les déclare) est périmé depuis qu'on peut faire les deux à la fois

Code :
  1. void lecture(char *t)
  2. {
  3.   ...
  4. }


 
3) la fonction "gets" doit recevoir un "char *". Si tu lui passes "*t", tu lui passes un "char". Ce n'est pas ce qu'elle attend.
Quand tu écris "char *t", tu définis deux item
a) tu définis l'item "etoile t" de type "char"
b) tu définis l'item "t" de type "char étoile"
Les deux item ont leur utilité et sont utilisables (si on le fait correctement)
Donc si la fonction "gets" attend un "char étoile", passe lui un "char étoile" donc passe-lui simplement "t". C'est d'ailleurs ce que tu fais quand tu appelles "lecture" qui attend un "char étoile", tu lui passes "t". Pourquoi changer avec "gets" qui attend la même chose ???
 
Une fois que tu auras corrigé cela, tu auras répondu à l'énoncé de l'exercice. Le problème c'est que, en utilisant "gets", tu ne limites pas la saisie. Et ainsi ta fonction "lecture" pourra tenter d'engranger plus de caractères que ce que ta zone "t" peut en stocker (et le C ne vérifie pas ça).
Il vaut donc mieux ne pas (ne jamais) utiliser "gets" mais "fgets" qui permet de donner une limite à la saisie.


Message édité par Sve@r le 06-09-2005 à 11:10:50
Reply

Marsh Posté le 06-09-2005 à 10:49:40    

merci bien :)

Reply

Marsh Posté le 06-09-2005 à 13:58:34    

c'etait quoi l'idée geniale presidant a la creation de la vieille formulation ? (la void truc(t) char *t { ..} )


Message édité par chrisbk le 06-09-2005 à 13:58:56
Reply

Marsh Posté le 07-09-2005 à 13:29:41    


 
moi je dirais que FGETS ben c'est pas encore génial non plus!  
 
faut utilisé GETCHAR()
une petite boucle et c'est parti ;)
 

Code :
  1. void lecture (char *t, int longueurmax)
  2. {
  3.    int i=0;
  4.    do
  5.    {
  6.       t = getchar();
  7.       i++;
  8.       t++;
  9.    } while (i<longueurmax && *(t-1) != '\\n');
  10.    *(t-1) = '\\0';
  11. }


 
Voila le programme est correcte mtn! ;-) quelques petite fautes de frappe vite corrigées ;)


Message édité par moi23372 le 07-09-2005 à 13:36:29
Reply

Marsh Posté le 07-09-2005 à 13:30:56    

moi23372 a écrit :

moi je dirais que FGETS ben c'est pas encore génial non plus!  
 
faut utilisé GETCHAR()
une petite boucle et c'est parti ;)
 

Code :
  1. void lecture (char *t, int longueurmax)
  2. {
  3.    int i=0;
  4.    do
  5.    {
  6.       t = getchar();
  7.       i++;
  8.       t++;
  9.    } while (i<longueurmax && *(t-1) != '\n');
  10.    *(t-1) = '\0';
  11. }



 
N'oublie quand-même pas de rajouter le '\0' final, sinon ce n'est plus une chaîne !!!


Message édité par Sve@r le 07-09-2005 à 13:36:44
Reply

Marsh Posté le 07-09-2005 à 13:30:56   

Reply

Marsh Posté le 07-09-2005 à 13:37:03    

*t = getchar();
 
 
bande de solicoque palmipede

Reply

Marsh Posté le 07-09-2005 à 13:40:00    

moi23372 a écrit :

moi je dirais que FGETS ben c'est pas encore génial non plus!


 
Pour quelle raison ?

Reply

Marsh Posté le 07-09-2005 à 13:41:38    

pis il est bugueux ce code, nom d'un sexe d'autriche

Reply

Marsh Posté le 07-09-2005 à 13:53:22    

chrisbk a écrit :

pis il est bugueux ce code, nom d'un sexe d'autriche


 
Ah oui, je m'étais arrêté au "faut pas utiliser fgets()" moi  [:mlc]  
 
C'est vraiment la peine de s'embêter avec un getchar() si c'est pour écrire ce genre de chose.  [:pingouino]

Reply

Marsh Posté le 07-09-2005 à 14:18:05    

chacun fait ce qu'il faut! Je ne suis pas certain que FGETS est standars sur tout les compilateurs! Or getchar est standars sur tout les compilo, donc portable!  
Mon code n'est pas infesté de bug, même si j'ai oublié une étoile! Elle fait tout ce qu'il faut pour faire une saisie clavier tout simplement!

Reply

Marsh Posté le 07-09-2005 à 14:20:27    

non, y plante, ton code

Reply

Marsh Posté le 07-09-2005 à 14:21:38    

moi23372 a écrit :

faut utilisé GETCHAR()
une petite boucle et c'est parti ;)
Voila le programme est correcte mtn! ;-) quelques petite fautes de frappe vite corrigées ;)


 
Correct ? Non. (Probablement jamais compilé, donc jamais testé...)
 
Ceci fonctione :  
[EDIT] : Nouvelle version sécurisée.

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. char *get_line (char *t, size_t longueurmax)
  4. {
  5.    char *p = NULL;
  6.    if (t != NULL && longueurmax > 0)
  7.    {
  8.       size_t i = 0;
  9.       int c = 0;
  10.       while (i < longueurmax - 1
  11.              && (c = getchar ()) != '\n'
  12.              && c != EOF)
  13.       {
  14.          t[i] = c;
  15.          i++;
  16.       }
  17.       t[i] = '\0';
  18.       /* purge ?*/
  19.       if (c != '\n')
  20.       {
  21.          while ((c = getchar ()) != '\n'
  22.                 && c != EOF)
  23.          {
  24.          }
  25.       }
  26.       if (c != EOF)
  27.       {
  28.          p = t;
  29.       }
  30.    }
  31.    return p;
  32. }
  33. int main (void)
  34. {
  35.    char s[10] = "??????????";
  36.    get_line (s, sizeof s);
  37.    printf ("'%s' (%u)\n", s, (unsigned) strlen (s));
  38.    return 0;
  39. }


 


Hello world
'Hello wor' (9)


 
[EDIT] Ouin: Pourquoi quand je tape '\n', ça affiche 'n' dans [fixed ] et [cpp ]? C'est nouveau ? Et '\0', ça fait un carré. C'est quoi ce bins!


Message édité par Emmanuel Delahaye le 07-09-2005 à 15:20:50

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 07-09-2005 à 14:25:25    

moi23372 a écrit :

chacun fait ce qu'il faut! Je ne suis pas certain que FGETS est standars sur tout les compilateurs! Or getchar est standars sur tout les compilo, donc portable!


 
Euh faut arrêter, fgets() c'est du C89, ça fait plus de quinze ans que c'est standard. :o
 

moi23372 a écrit :

Mon code n'est pas infesté de bug, même si j'ai oublié une étoile! Elle fait tout ce qu'il faut pour faire une saisie clavier tout simplement!


 
C'est déjà un bon gros bug.
 
EDIT : Ah ouais zarb le coup du '\n' dans le [ fixed], je pensais que c'était une erreur de moi686554.


Message édité par Elmoricq le 07-09-2005 à 14:27:26
Reply

Marsh Posté le 07-09-2005 à 14:31:56    

nan par contre je crois qu'il compte mal ses caracteres [:zaib3k]

Reply

Marsh Posté le 07-09-2005 à 14:32:01    

j'aime bien veux bien un gros bug! mais je ne l'ai pas testé, j'ai fais ça de mémoire en 30 secondes!
Mon code marche, je viens de le tester ;)  
 

Code :
  1. /**********************************************************************************/
  2. /*INPUT: adresse du vecteur + le nombre d'élément maximum.                        */
  3. /*PROCESS: lecture d'une chaine de caracteres                                     */
  4. /*OUTPUT: retour du nombre d'éléments                                             */
  5. /**********************************************************************************/
  6. int LireVchar (char *p, int n)
  7. {
  8. int i=0;
  9. do
  10. {
  11.  *p=getchar();
  12.  i++;
  13.  p++;
  14. } while (i<n && *(p-1) != '\\n');
  15. *(p-1) = '\\0';
  16. return(i-1);
  17. }


Message édité par moi23372 le 07-09-2005 à 14:33:11
Reply

Marsh Posté le 07-09-2005 à 14:34:55    

moi23372 a écrit :

j'aime bien veux bien un gros bug! mais je ne l'ai pas testé, j'ai fais ça de mémoire en 30 secondes!
Mon code marche, je viens de le tester ;)  
 

Code :



 
 
Euuh :
 

char *lecture(char *t, size_t maxlength)
{
    if ( t )
       fgets(t, maxlength, stdin);
    return t;
}


 
Et puis ça ne mérite même pas une fonction ce truc.  [:petrus75]


Message édité par Elmoricq le 07-09-2005 à 14:41:36
Reply

Marsh Posté le 07-09-2005 à 14:37:49    

char toto[2]
 
LireVchar (toto, 2);
 
je sens le segfault
 

Reply

Marsh Posté le 07-09-2005 à 14:38:54    

Ah nan j'avais pas vu la feinte, rien dit

Reply

Marsh Posté le 07-09-2005 à 14:40:17    

chrisbk a écrit :

Ah nan j'avais pas vu la feinte, rien dit


 
 
Ouais enfin ceci dit, suffit de faire : "LireVchar(NULL, -1);"

Reply

Marsh Posté le 07-09-2005 à 14:41:12    

[:ddr555]

Reply

Marsh Posté le 07-09-2005 à 14:42:07    

oui ça va! quand on veut faire planter un programme il y a tjs moyen! Naturellement faut savoir programmer aussi, passer null c'est une erreur de débutant!
Et puis merde, c'est du C, les fonctions ne sont pas destinées ici à être réutillisé comme les classes! :D Vive la POO

Reply

Marsh Posté le 07-09-2005 à 14:43:47    

moi23372 a écrit :

Et puis merde, c'est du C, les fonctions ne sont pas destinées ici à être réutillisé comme les classes! :D Vive la POO


 
Ben et les shared-lib, elles servent à quoi alors ?  [:itm]

Reply

Marsh Posté le 07-09-2005 à 14:43:47    

ne pas vérifier NULL c'est une erreur de jeanjean [:vague nocturne]
 
bin oui c'est du C, un langage de merde par excellence, tout a fait, enfin meme en C++ faut vérifier les NULL

Reply

Marsh Posté le 07-09-2005 à 14:45:08    

oui mais la POO dispose des exceptions! Il y a tjs moyen d'intercepter ce genre d'erreur!  
Puis il aurait ici suffit simplement de faire
 
if (t == null || n <= 0)
   return -1;


Message édité par moi23372 le 07-09-2005 à 14:46:41
Reply

Marsh Posté le 07-09-2005 à 14:51:20    

moi23372 a écrit :

j'aime bien veux bien un gros bug! mais je ne l'ai pas testé, j'ai fais ça de mémoire en 30 secondes!
Mon code marche, je viens de le tester ;)


 
C'est OK, mais ces '-1', c'est un peu compliqué . Et puis comme tu as un index (i), autant utiliser directement la notation [i] et laisser le pointeur tranquille (il n'est jamais bon de modifier un paramètre).
 
D'autre part, si on passe NULL, le comportement est indéfini.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 07-09-2005 à 14:53:15    

Elmoricq a écrit :


char *lecture(char *t, size_t maxlength)
{
    if ( t )
       fgets(t, maxlength, stdin);
    return t;
}




Pas pareil (tu laisses le '\n');
 
Nota dans les deux cas, stdin n'est pas purgé en cas de débordement. En plus, on a aucun moyen de le savoir.
 
J'ai integré une purge à mon code. La fonction s'appelle get_line() et elle est libre ! Si on ne veut pas de la purge automatique, on prends fgets()...


Message édité par Emmanuel Delahaye le 07-09-2005 à 15:07:42

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed