va_start va_end与fatfs f_printf

时间:2015-06-04 16:06:55

标签: c

我正在尝试实现一个写入sdcard的函数。它应该像printf一样调用,带有附加的可选参数:

    void writeDataToFiles(int anything,
        const TCHAR* fmt, ...){
             ....
            va_list args;
            va_start(args, fmt);
            f_printf(file, fmt, args); //this doesnt work
            vPrintf(fmt, args); //this works
            va_end(args);
            f_sync(file);
...
}

我试着像这样称呼它

int m=5
writeDataToFiles(0,"my int value %i\n", m);

vPrintf可以正常工作,但是f_printf只是用“i”保存字符串而不是用实际值替换它

这是f_printf实现

    /*-----------------------------------------------------------------------*/
/* Put a formatted string to the file                                    */
/*-----------------------------------------------------------------------*/
int f_printf(FIL* fil, /* Pointer to the file object */
const TCHAR* str, /* Pointer to the format string */
... /* Optional arguments... */
) {
    va_list arp;
    BYTE f, r;
    UINT i, j, w;
    ULONG v;
    TCHAR c, d, s[16], *p;
    int res, cc;

    va_start(arp, str);

    for (cc = res = 0; cc != EOF; res += cc) {
        c = *str++;
        if (c == 0)
            break; /* End of string */
        if (c != '%') { /* Non escape character */
            cc = f_putc(c, fil);
            if (cc != EOF)
                cc = 1;
            continue;
        }
        w = f = 0;
        c = *str++;
        if (c == '0') { /* Flag: '0' padding */
            f = 1;
            c = *str++;
        } else {
            if (c == '-') { /* Flag: left justified */
                f = 2;
                c = *str++;
            }
        }
        while (IsDigit(c)) { /* Precision */
            w = w * 10 + c - '0';
            c = *str++;
        }
        if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
            f |= 4;
            c = *str++;
        }
        if (!c)
            break;
        d = c;
        if (IsLower(d))
            d -= 0x20;
        switch (d) { /* Type is... */
            case 'S': /* String */
                p = va_arg(arp, TCHAR*);
                for (j = 0; p[j]; j++)
                    ;
                res = 0;
                while (!(f & 2) && j++ < w)
                    res += (cc = f_putc(' ', fil));
                res += (cc = f_puts(p, fil));
                while (j++ < w)
                    res += (cc = f_putc(' ', fil));
                if (cc != EOF)
                    cc = res;
                continue;
            case 'C': /* Character */
                cc = f_putc((TCHAR) va_arg(arp, int), fil);
                continue;
            case 'B': /* Binary */
                r = 2;
                break;
            case 'O': /* Octal */
                r = 8;
                break;
            case 'D': /* Signed decimal */
            case 'U': /* Unsigned decimal */
                r = 10;
                break;
            case 'X': /* Hexdecimal */
                r = 16;
                break;
            default: /* Unknown type (passthrough) */
                cc = f_putc(c, fil);
                continue;
        }

        /* Get an argument and put it in numeral */
        v = (f & 4) ? va_arg(arp, long) : ((d == 'D') ? (long) va_arg(arp, int)
                : va_arg(arp, unsigned int));
        if (d == 'D' && (v & 0x80000000)) {
            v = 0 - v;
            f |= 8;
        }
        i = 0;
        do {
            d = (TCHAR) (v % r);
            v /= r;
            if (d > 9)
                d += (c == 'x') ? 0x27 : 0x07;
            s[i++] = d + '0';
        } while (v && i < sizeof(s) / sizeof(s[0]));
        if (f & 8)
            s[i++] = '-';
        j = i;
        d = (f & 1) ? '0' : ' ';
        res = 0;
        while (!(f & 2) && j++ < w)
            res += (cc = f_putc(d, fil));
        do
            res += (cc = f_putc(s[--i], fil));
        while (i);
        while (j++ < w)
            res += (cc = f_putc(' ', fil));
        if (cc != EOF)
            cc = res;
    }

    va_end(arp);
    return (cc == EOF) ? cc : res;
}

编辑: 我试图使用va_list作为f_print方法的参数,但它仍然无法工作:

int f_printf(FIL* fil, /* Pointer to the file object */
const TCHAR* str, /* Pointer to the format string */
va_list arp /* Optional arguments... */
) {
    BYTE f, r;
    UINT i, j, w;
    ULONG v;
    TCHAR c, d, s[16], *p;
    int res, cc;
    for (cc = res = 0; cc != EOF; res += cc) {
        c = *str++;
        if (c == 0)
            break; /* End of string */
        if (c != '%') { /* Non escape character */
            cc = f_putc(c, fil);
            if (cc != EOF)
                cc = 1;
            continue;
        }
        w = f = 0;
        c = *str++;
        if (c == '0') { /* Flag: '0' padding */
            f = 1;
            c = *str++;
        } else {
            if (c == '-') { /* Flag: left justified */
                f = 2;
                c = *str++;
            }
        }
        while (IsDigit(c)) { /* Precision */
            w = w * 10 + c - '0';
            c = *str++;
        }
        if (c == 'l' || c == 'L') { /* Prefix: Size is long int */
            f |= 4;
            c = *str++;
        }
        if (!c)
            break;
        d = c;
        if (IsLower(d))
            d -= 0x20;
        switch (d) { /* Type is... */
            case 'S': /* String */
                p = va_arg(arp, TCHAR*);
                for (j = 0; p[j]; j++)
                    ;
                res = 0;
                while (!(f & 2) && j++ < w)
                    res += (cc = f_putc(' ', fil));
                res += (cc = f_puts(p, fil));
                while (j++ < w)
                    res += (cc = f_putc(' ', fil));
                if (cc != EOF)
                    cc = res;
                continue;
            case 'C': /* Character */
                cc = f_putc((TCHAR) va_arg(arp, int), fil);
                continue;
            case 'B': /* Binary */
                r = 2;
                break;
            case 'O': /* Octal */
                r = 8;
                break;
            case 'D': /* Signed decimal */
            case 'U': /* Unsigned decimal */
                r = 10;
                break;
            case 'X': /* Hexdecimal */
                r = 16;
                break;
            default: /* Unknown type (passthrough) */
                cc = f_putc(c, fil);
                continue;
        }

        /* Get an argument and put it in numeral */
        v = (f & 4) ? va_arg(arp, long) : ((d == 'D') ? (long) va_arg(arp, int)
                : va_arg(arp, unsigned int));
        if (d == 'D' && (v & 0x80000000)) {
            v = 0 - v;
            f |= 8;
        }
        i = 0;
        do {
            d = (TCHAR) (v % r);
            v /= r;
            if (d > 9)
                d += (c == 'x') ? 0x27 : 0x07;
            s[i++] = d + '0';
        } while (v && i < sizeof(s) / sizeof(s[0]));
        if (f & 8)
            s[i++] = '-';
        j = i;
        d = (f & 1) ? '0' : ' ';
        res = 0;
        while (!(f & 2) && j++ < w)
            res += (cc = f_putc(d, fil));
        do
            res += (cc = f_putc(s[--i], fil));
        while (i);
        while (j++ < w)
            res += (cc = f_putc(' ', fil));
        if (cc != EOF)
            cc = res;
    }

    return (cc == EOF) ? cc : res;
}

0 个答案:

没有答案