簡単な答え: はい、両方のソリューションを実行することは完全に可能です。
すべてのデータ型と形式をサポートしたい場合、printf 関数は非常に複雑です。しかし、いくつかの異なる基数で文字列または整数を出力できるものを書くことはそれほど難しくありません (ほとんどの人は 10 進数と 16 進数しか必要としませんが、8 進数は、10 進数と 16 進数があれば、おそらくさらに 3 ~ 4 行のコードを追加するだけです)。
通常、printf は次のように記述されます。
int printf(const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt)
ret = do_xprintf(outputfunc, NULL, fmt, args);
va_end(args);
return ret;
}
そして、do_xprintf()
すべてのバリアント (printf、sprintf、fprintf など) のハードワークをすべて実行します。
int do_xprintf(void (*outputfunc)(void *extra, char c), void *extra, const char *fmt, va_list args)
{
char *ptr = fmt;
while(1)
{
char c = *ptr++;
if (c == '%')
{
c = *ptr++; // Get next character from format string.
switch(c)
{
case 's':
char *str = va_arg(args, const char *);
while(*str)
{
count++;
outputfunc(extra, *str);
str++;
}
break;
case 'x':
base = 16;
goto output_number;
case 'd':
base = 10;
output_number:
int i = va_arg(args, int);
// magical code to output 'i' in 'base'.
break;
default:
count++;
outputfunc(extra, c);
break;
}
else
count++;
outputfunc(extra, c);
}
return count;
}
あとは、上記のコードの一部を埋めて、シリアル ポートに出力する outputfunc() を記述するだけです。
これは大まかなスケッチであり、コードにいくつかのバグがあると確信していることに注意してください-浮動小数点または「幅」をサポートしたい場合は、もう少し作業する必要があります...
(追加のパラメータに注意してください -FILE *
ファイルポインタになるa への出力のsprintf
場合、 for 、バッファの構造体とバッファ内の位置などを渡すことができます)