2013-12-16 52 views
-6

有什麼辦法可以縮短下面這段代碼嗎?也許有一種方法只能使用一個sprintf命令,但我不知道如何。當其值爲零時,我需要避免打印x如何在其值爲零時不打印整數?

char msg[1000]; 

string s1 = "s1"; 
string s2 = "s2"; 
string s3 = "s3"; 

int x = 0; 

if(x == 0) 
    sprintf(msg, "%s,%s,%s \n", s1.c_str(), s2.c_str(), s3.c_str()); 
else 
    sprintf(msg, "%s,%s,%s,%d \n", s1.c_str(), s2.c_str(), s3.c_str(), x); 

回答

1

由於您使用C++,爲什麼不使用stringstream建立自己的緩衝區件:

#include <cstdio> 
#include <sstream> 
#include <string> 

using namespace std; 

int main() { 
    string s1 = "s1"; 
    string s2 = "s2"; 
    string s3 = "s3"; 
    int x = 0; 

    stringstream ss; 
    ss << s1 << "," << s2 << "," << s3; 
    if (x != 0) 
     ss << "," << x; 
    ss << " " << endl; 

    // Don't do this! See link below 
    //const char* c = ss.str().c_str(); 

    string result = ss.str(); 
    const char* c = result.c_str(); 

    printf("Result: '%s'\n", c); 
    getchar(); 
    return 0; 
} 
+0

由於解決方案的性能對我來說也很重要,你知道如果使用'stringstream'比'sprintf'少或者更有效嗎? – Meysam

+0

表現總是很重要。問題是,它是最重要的*嗎?我現在不知道答案,現在也不會擔心。以清晰,簡明的方式編寫代碼,然後進行優化。不成熟的優化是萬惡之源。 –

+0

感謝您的努力和優雅的解決方案! – Meysam

0

簡單,打破它分成幾部分:

printf("%s,%s,%s", s1.c_str(), s2.c_str(), s3.c_str()); // no newline 
if(x != 0) 
    printf(",%d", x); 
printf(" \n"); 

當試圖做這樣的事情,把它當做一道數學題:分解出兩種說法之間有什麼共同點,這樣做不管有沒有if條件。

如果你想使用sprintf(因爲你改變了你的問題),你需要將指針調整到每次傳遞的緩衝區中,以說明已寫入的內容。另外,您應該使用帶有長度參數的snprintf,以確保不會超出緩衝區。這個長度也需要在每一步之後調整。

+0

更新我的問題。 – Meysam

+0

@Meysam你真的想把這個'sprintf'變成緩衝區嗎?或者它會在'stdout'結束' –

+0

我需要將'msg'傳遞給需要'char *'作爲參數的函數。 – Meysam

1

由於printf系列函數會評估但忽略任何未使用的參數,因此這將是一個選項;

sprintf(msg, x == 0 ? "%s,%s,%s \n" : "%s,%s,%s,%d \n", 
      s1.c_str(), s2.c_str(), s3.c_str(), x); 

爲了便於閱讀和清晰起見,我會親自保留當前版本。在真正被證明是一個問題之前,可讀性勝過任何一天的微觀優化。

+0

這兩個代碼都有一個分支。你的可能不是一個優化。 –

+0

@MatthewLundberg是的,這取決於編譯器,因爲大多數非算法優化都可以。使用gcc進行快速測試似乎可以節省一些_code的大小,而不是速度,因爲c_str只被稱爲3個地方而不是6個,但這當然不一定是真的。 –