2014-10-10 53 views
0

是否有像printf這樣的函數可以返回一個字符串而不是打印它?我有一個函數用特定的顏色打印字符串,但它必須是字符串文字,而不是像printf那樣接受變量。printf返回一個字符串

// Function declaration (Assums YELLOW and NORMAL are the unix constants for terminal colors 
void pYellow(char *str) { 
    printf("%s%s%s", YELLOW, str, NORMAL); 
} 

//Function call 
void pYellow("This is a string"); 

如果我想打印顏色與變量,它不會工作。像pYellow("Num: %d", 42);會給出一個錯誤,因爲它有太多的參數。做pYellow(printf("String"));也不行。

TL:DR我想知道是否有printf方法返回一個字符串,而不是打印它。

+1

您可以使用'dom0'建議的snprintf,或者您可以使用一個動態分配內存並返回一個指針的函數。有一種叫做'asprintf'的非標準格式,但是你可以通過委託給'vsnprintf'在幾行中用標準C實現它。 – 2014-10-10 02:07:12

+0

http://en.cppreference.com/w/cpp/io/c/fprintf – 2014-10-10 02:09:11

+0

另請參見[AIX上'asprintf()'的替代或替代方法](http://stackoverflow.com/questions/4899221/substitute - 或解決方法換asprintf-ON-AIX)。 – 2014-10-10 18:29:26

回答

2

使用snprintf

int snprintf(char *str, size_t size, const char *format, ...); 
  • str是你分配的緩衝區(例如malloc()
  • size是緩衝
  • 大小的格式化字符串存儲在str呼叫後。
  • 還有sprintf從來沒有使用它

您也可以創建自己的使用v*printf家庭的功能printf樣的功能。最簡單的例子:

#include <stdarg.h> 
// required for va_list, va_start, va_end 

void customPrintf(const char* format, /* additional arguments go here */ ...) 
{ 
    va_list args; 
    va_start(args, format); 
    // set color here (for example) 
    vprintf(format, args); 
    // reset color 
    va_end(args); 
} 
+0

不同意「'sprintf',千萬不要使用它」。 'snprintf()'也有它自己的問題。爲作業使用正確的工具並正確使用它。 char [sizeof(int)* CHAR_BIT/3 + 3]沒有任何不安全的地方; sprintf(buf,「%d」,some_int);'如果編碼器不能正確使用'sprintf()',正確使用'snprintf()'的機會不會太高,並且會帶來虛假的安全感。就像通過'strcpy()'推薦'strncpy()'一樣 - 將一組問題交換爲另一組問題。 – chux 2014-10-10 02:03:49

+0

@chux我仍然更喜歡'%d'的snprintf版本,你知道它不會緩衝溢出,而另一個你必須用你的大腦來檢查它(即使你不是100 %肯定)。 – 2014-10-10 02:08:33

+0

@Matt McNabb同意'snprintf()'可以防止緩衝區溢出。如果緩衝區不足,打印結果是錯誤的(截斷)。代碼仍然有問題。我們已經爲另一種交易了一種類型的問題。有爭議的是哪個更好,但最終,可靠代碼需要1)防止('sprintf()'route)或2)應付截斷('snprintf()'route)。 IAC - 我的觀點是,它並不總是_better_,但是聲明「'sprintf',從不使用它」並不是好建議,因爲「從不」。 – chux 2014-10-10 02:58:44