Hello i need some help for a function that I'm creating, it should perform some of the fuctions of the operand "printf". The problem I have with the funcion, is that I am unable to read the "Float" and "Double" type parameters, also i want to create a function that sorts the number of digits that is shown (%3 , %.5) and so on. If you could help I would be greatfull.
Thanks for your time. Regards, Daniel
Here is the code im using:

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
char * convert(unsigned int, int);
void echo(char *,...);
int *ftoa(float Fnum, char numStr[]);
int main()
{
    int i=65;
    float k=5.75;
    char str[]="This is my string";
    echo("\nMessage = %f",k);
    getchar();
}

void echo(char * frmt,...)
{
    float f;
    double d;
    char *p;
    int i;
    char *s;
    char fstr[40];
    va_list argp;
    va_start(argp, frmt);
    p=frmt;
    for(p=frmt; *p!='\0';p++)
    {
        if(*p!='%')
        {
            putchar(*p);continue;
        }
        p++;
        switch(*p)
        {
            case 'c':
                i=va_arg(argp,int);
                putchar(i);
                break;
            case 'd':
                i=va_arg(argp,int);
                if(i<0)
                {
                    i=-i;putchar('-');
                }
                puts(convert(i,10));
                break;
            case 's': 
                s=va_arg(argp,char *);
                puts(s);
                break;
            case 'f': 
                f=va_arg(argp,float);
                ftoa(f,fstr);
                break;
            case 'lf':
                d=va_arg(argp,double);
                puts(ftoa(f,fstr));
            case '%':
                putchar('%');
                break;
        }
    }
    va_end(argp);
}
char *convert(unsigned int num, int base)
{
    static char buff[33];
    char *ptr;
    ptr=&buff[sizeof(buff)];
    *ptr='\0';
    do
    {
        *--ptr="0123456789"[num%base];
        num/=base;
    }
    while(num!=0);
    return(ptr);
}
int *ftoa(float Fnum, char numStr[])
{
    int wholeNum=Fnum;
    int decimalNum=((Fnum - wholeNum) * 10000000);
    char wholeNumStr[13];
    char decNumStr[13];
    printf("WholeNum=%d",wholeNum);
    itoa(wholeNum, wholeNumStr,10);
    itoa(decimalNum, decNumStr,10);
    strcpy(numStr, wholeNumStr);
    strcat(numStr, ".");
    strcat(numStr, decNumStr);
    return puts(numStr);
}

In general, you would use one of the vprintf* functions to do this. From man vsnprintf:

   The functions vprintf(), vfprintf(), vsprintf(), vsnprintf() are equiv-
   alent  to  the  functions  printf(),  fprintf(), sprintf(), snprintf(),
   respectively, except that they are called with a va_list instead  of  a
   variable  number  of  arguments. These functions do not call the va_end
   macro. Consequently, the value of ap is undefined after the  call.  The
   application should call va_end(ap) itself afterwards.

The problem I have with the funcion, is that I am unable to read the "Float" and "Double" type parameters

Varargs are always promoted, so there's no such thing as a float type parameter. That's your biggest problem: instead of trying to extract an object of type float, you need to look for type double. You'll notice that printf() works the same way; there's not a specifier for float, all of the ones that mention floating-point work with double.

Here's the code cleaned up a little bit and fixed:

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

char* convert(unsigned int, int);
void echo(char*,...);
void ftoa(double Fnum);

int main()
{
    int i=65;
    float k=5.75;
    char str[]="This is my string";

    echo("Message = %f", k);

    return 0;
}

void echo(char* fmt, ...)
{
    char* p = fmt;
    int i;

    va_list argp;
    va_start(argp, fmt);

    for (; *p != '\0'; ++p)
    {
        if (*p != '%')
        {
            putchar(*p);
            continue;
        }

        switch (*++p)
        {
            case 'c':
                putchar(va_arg(argp, char));
                break;
            case 'd':
                i = va_arg(argp, int);

                if (i < 0)
                {
                    i = -i;
                    putchar('-');
                }

                puts(convert(i, 10));
                break;
            case 's': 
                puts(va_arg(argp, char*));
                break;
            case 'f': 
                ftoa(va_arg(argp, double));
                break;
            case '%':
                putchar('%');
                break;
        }
    }

    va_end(argp);
}

char *convert(unsigned int num, int base)
{
    static char buff[33];
    char *ptr;

    ptr=&buff[sizeof(buff)];
    *ptr='\0';

    do
    {
        *--ptr="0123456789"[num%base];
        num/=base;
    }
    while(num!=0);

    return(ptr);
}

void ftoa(double Fnum)
{
    int wholeNum=Fnum;
    int decimalNum=((Fnum - wholeNum) * 10000000);
    char wholeNumStr[13];
    char decNumStr[13];
    char numStr[13];

    itoa(wholeNum, wholeNumStr,10);
    itoa(decimalNum, decNumStr,10);
    strcpy(numStr, wholeNumStr);
    strcat(numStr, ".");
    strcat(numStr, decNumStr);
    puts(numStr);
}

I made several changes, but the key one is ftoa(va_arg(argp, double));. Note the type was changed from float to double.

This article has been dead for over six months. Start a new discussion instead.