2013-12-16 31 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个,但这当然不一定是真的。 –