Programmer la fonction c

wakhma Messages postés 11 Statut Membre -  
KX Messages postés 19031 Statut Modérateur -
Bonjour,
je suis en train d'apprendre le langage C. je voudrai programmer la fonction printf avec d'autre fonction comme var_ap var_argv va_start write...
je compren pas le resultat. Qui peut m'aider. Merci

voici mon code:
#include "myprintf.h"
int myprintf(const char* format, ...)
{
int i=0;
char* s=NULL;
va_list ap;
va_start(ap, format);

while(format[i] != 0)
{
switch(format[i])
{
case '%':
//printf("%d\n",&format[] );
switch(format[i++])
{
case 's':
//write(1, va_arg(ap, char), sizeof(char));
write(1, s=va_arg(ap, char*), (size_t)strlen(s));
break;
case 'd':
write(1, va_arg(ap, int), sizeof(int));
break;
case 'c':
write(1, va_arg(ap, char), sizeof(char));
break;
default:
write(1, "%", sizeof(char));
write(1, &format[i], sizeof(char));
}
break;
default :
write(1, &format[i], sizeof(char));
}
i++;
}

va_end(ap);
return 0;
}

Et le main:

#include "main.h"
#include "myprintf.h"

int main(int argc, char* argv[])
{
int a=1;

printf("\nExemple 1 : \n");
myprintf("1 - une chaine\n");
myprintf("2 - %s\n", "une autre chaine");
myprintf("3 - %i\n", 42);
myprintf("4 - %s %d %s%c\n", "avec", 4, "parametres", '\n');
return 0;
}

2 réponses

  1. KX Messages postés 19031 Statut Modérateur 3 020
     
    Il faut distinguer i++ et ++i pour savoir dans quel ordre l'incrémentation est effectuée

    switch(format[i])
    {
        case '%':
           switch(format[++i])
    0
    1. wakhma
       
      Salut merci pour votre retour, j'ai essayer avec les deux méthodes. Quand je fais ++i sa fais un segmentation fault.
      0
    2. KX Messages postés 19031 Statut Modérateur 3 020
       
      Tu as segmentation fault sur le %d de l'exemple 4, mais les trois premiers exemples sont bons.
      0
    3. wakhma
       
      Non le seg fault c sur le %s. voici mon main et le résultat:
      #include "main.h"
      #include "myprintf.h"

      int main(int argc, char* argv[])
      {
      int a=1;


      printf("\nExemple 1 : \n");
      myprintf("1 - une chaine\n");
      //myprintf("2 - %s\n", "une autre chaine");
      myprintf("3 - %i\n", 42);
      myprintf("3====> - %d\n", 42);
      myprintf(" ====> - %c\n", "parametres");
      myprintf("4 - %s %d %s%c\n", "avec", 4, "parametres", '\n');
      return 0;
      }


      Exemple 1 :
      1 - une chaine
      3 - %i
      3====> -
      ====> - Illegal instruction: 4
      0
    4. KX Messages postés 19031 Statut Modérateur 3 020
       
      Tu as changé le main depuis tout à l'heure, donc forcément ça change le résultat. D'autant que tu as peut-être changé d'autres choses dans ton code, donc comment s'y retrouver ?

      Moi je me basais sur ton code initial, et avec le i++ tu n'avais aucun % qui ne fonctionnait, alors qu'avec le ++i les %s fonctionnent, même si cela provoquait des erreurs pour %d et %c.

      Si tu veux parler de ton nouveau code, donne le nous, mais si je prends ton code initial avec la seule modification du ++i alors tu devrais avoir une erreur sur le %d, pas sur les %s
      0
  2. wakhma
     
    ok je vous envoie mon nouveau code:

    #include "myprintf.h"
    int myprintf(const char* format, ...)
    {
    int i=0;
    char* s=NULL;
    va_list ap;
    va_start(ap, format);

    while(format[i] != 0)
    {
    switch(format[i])
    {
    case '%':
    //printf("%d\n",&format[] );
    switch(format[++i])
    {
    case 's':
    //write(1, va_arg(ap, char), sizeof(char));
    write(1, s=va_arg(ap, char*), (size_t)strlen(s));

    break;
    case 'd':
    write(1, va_arg(ap, int), sizeof(int));
    break;
    case 'c':
    write(1, va_arg(ap, char), sizeof(char));
    break;
    default:
    write(1, "%", sizeof(char));
    write(1, &format[i], sizeof(char));
    }
    break;
    default :
    write(1, &format[i], sizeof(char));
    }
    i++;
    }

    va_end(ap);
    return 0;
    }

    Et le main :
    #include "main.h"
    #include "myprintf.h"

    int main(int argc, char* argv[])
    {
    int a=1;

    printf("\nExemple 1 : \n");
    myprintf("1 - une chaine\n");
    //myprintf("2 - %s\n", "une autre chaine");
    myprintf("3 - %i\n", 42);
    myprintf("3====> - %d\n", 42);
    myprintf(" ====> - %c\n", "parametres");
    myprintf("4 - %s %d %s%c\n", "avec", 4, "parametres", '\n');
    return 0;
    }
    0
    1. KX Messages postés 19031 Statut Modérateur 3 020
       
      Et bien il s'agit encore d'une erreur sur les %d et les %c, en aucun cas sur %s qui fonctionne.

      Le problème c'est ton write, tu passes en deuxième argument un entier (pour %d) alors que l'on attends un pointeur sur une chaîne de caractère, ensuite ton troisième argument devrait correspondre à la taille de cette chaîne de caractères et ce n'est pas le cas non plus !
      0
    2. wakhma
       
      Merci KX mais si j'ajoute un * après int pour sa pointe sur la chaine de caractère il m'affiche que les premières lettres genre comme ceci :

      Exemple 1 :
      1 - une chaine
      2 - u
      3 - %i
      4 - a p
      0
    3. KX Messages postés 19031 Statut Modérateur 3 020
       
      Il ne s'agit pas de rajouter des *, mais de transformer ton entier en chaines de caractères, c'est à dire utiliser itoa ou une fonction équivalente.
      0
    4. wakhma
       
      aucune idée sur cette fonction itoa.
      0
    5. KX Messages postés 19031 Statut Modérateur 3 020
       
      itoa est une fonction de conversion pour passer de l'entier int à un char* qui représente l'entier.
      On passe donc de 42 à "42", c'est indispensable puisque c'est un char* que tu affiches avec write.
      0