Kurze Antwort: Ja, es ist durchaus möglich, beide Lösungen zu verwenden.
Die printf-Funktion ist sehr komplex, wenn Sie alle Datentypen und Formate unterstützen möchten. Aber es ist nicht so schwer, etwas zu schreiben, das einen String oder eine ganze Zahl in ein paar verschiedenen Basen ausgeben kann (die meisten Leute benötigen nur Dezimal und Hex, aber Oktal fügt wahrscheinlich nur noch 3-4 Zeilen Code hinzu, sobald du Dezimal und Hex hast).
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;
}
Und dann do_xprintf()
macht die ganze harte Arbeit für alle Varianten (printf, sprintf, fprintf, etc)
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;
}
, alle jetzt:
Typischerweise wird printf wie folgt geschrieben Sie müssen nur ein paar Bits des obigen Codes ausfüllen und eine outputfunc() schreiben, die an Ihren seriellen Port ausgegeben wird.
Beachten Sie, dass dies eine grobe Skizze ist, und ich bin sicher, dass es einige Bugs im Code gibt - und wenn Sie Fließkomma oder "Breiten" unterstützen wollen, müssen Sie ein bisschen mehr daran arbeiten ...
(Hinweis auf den zusätzlichen Parameter - für die Ausgabe auf einem FILE *
, dass der Dateizeiger für sprintf
sein würde, Sie eine Struktur für den Puffer und die Position in dem Puffer, oder so etwas passieren kann)
Ja, es ist möglich - Sie können Ihre eigenen Ausgaberoutinen, finden Sie eine kleines Stand-alone Teil printf() Implementierung schreiben, oder schreiben Sie die notwendige Back-End-Unterstützung, um diese Funktionen von einem minimimal eingebettet libc zu ermöglichen (wahrscheinlich in Ihrer Toolchain enthalten), um auf Ihrer Plattform zu laufen. –
Danke. Ich habe gehört, dass Newlib als eingebettete Libc in Ordnung ist. Ich werde jedoch zuerst nach einem partiellen printf() suchen. – Sam
@ChrisStratton: Es hängt effektiv vom Betriebssystem ab. Es ist möglich, dass die systemeigenen OS-Routinen die Standardbibliothek sind. –