2012-07-02 55 views
2

創建帶有一些附加功能的snprintf()版本的最簡單方法是什麼?例如附加的格式說明符可以重複指定次數的以下轉換?例如,像%6a%-3x這樣的東西將接受參數列表中的char*參數,並且如果這指向字符串"My test string"將打印"4d 79 20 74 65 73 74 "。關聯的參數總是一個指向相應類型數組的指針。創建printf的自定義版本

這是代碼來解釋格式說明符和可變長度參數列表(其類型取決於格式字符串中的格式說明符),我希望有一些幫助,以避免重新發明輪子。

這需要使用普通的老式C語言,因爲它必須使用Microchip的PIC C30編譯器進行編譯。

謝謝 - 羅文

+13

[下載開源實現](http://www.gnu.org/software/libc/download.html)'printf'並對其進行破解。 –

+0

@JonathonReinhart然後被迫釋放你爲這個項目編寫的所有其他代碼,因爲它是一個「派生工作」。絕對沒有人可以反對!這就是說,對於OP來說,還有更多的寬鬆許可的stdio/libc在那裏;如果沒有別的,只需從其中一個BSD變體中抽取一個。 – tbert

+0

夥計們,如果你真的認爲hacking printf是正確的方法,你真的需要檢查vsprintf。 –

回答

2

vsprintf是你在找什麼。它可以讓你編寫自己的類似sprintf的函數,它接受可變數量的參數,然後讓你在進行調用之前做你需要的。

這裏是我用它來實現自己的printf到USB端點在嵌入式設備中的例子:

#include <stdarg.h> 
void uprintf(char *fmt, ...) { 
    va_list args; 
    va_start(args, fmt); 
    vsprintf(str_buffer, fmt, args); 
    usb_write(str_buffer); 
    va_end(args); 
} 

在你的情況,你可以「攔截」的格式調用vsprintf,字符串並將自己的語法擴展爲適當的格式說明符語法,然後將新的格式說明符和變量arg列表傳遞到vsprintf

void your_printf(char *fmt, ...) { 
    char new_fmt_string[1024]; /* make sure you allocate enough space */ 
    va_list args; 

    /* here, do your transformation on the fmt string */ 

    va_start(args, new_fmt_string); 
    vsprintf(str_buffer, new_fmt_string, args); 

    /* now take your fully formatted string and do something with it */ 

    /* then clean up */ 
    va_end(args); 
} 
+0

但是沒有便攜的方式來轉換例如const char(*)[3]'到'%-3x%-3x%-3x'的一個好參數列表。 – aschepler

+0

我只是給了他他所要求的:這是'代碼來解釋格式說明符'和'可變長度參數列表',我想幫助一些,以避免重新發明輪子。 :-) –

1

最簡單的方法可能不是你想要的答案,但它可能是最實際的解決方案:不要這樣做。

取而代之,創建您自己的寫入緩衝區的輸出函數。

// print count bytes from buf into s, but take up no more than n-1 bytes 
// returns how many bytes were (or would be) printed 
int snprint_hex (char *s, size_t n, const char *buf, size_t count) { 
    //... 
} 

您的代碼會更清楚,你將不必實現神祕的解析代碼來處理所有的printf格式說明。