我正在尝试实现一个写入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;
}