2012-06-11 155 views
1

我想創建一個公共的API,將一個字符串作爲參數,並將該字符串放置在放置格式說明符的另一個字符串中的位置處。如何用格式說明符創建一個字符串?

e.g. string PrintMyMessage(const string& currentValAsString) 
    { 
      string s1("Current value is %s",currentValAsString); 
      return s1; 
    } 

目前我得到以下生成錯誤。

1>d:\extra\creatingstrwithspecifier\creatingstrwithspecifier\main.cxx(8): error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::basic_string<_Elem,_Traits,_Ax> &,unsigned int,unsigned int)' : cannot convert parameter 2 from 'const std::string' to 'unsigned int' 
1>   with 
1>   [ 
1>    _Elem=char, 
1>    _Traits=std::char_traits<char>, 
1>    _Ax=std::allocator<char> 
1>   ] 
1>   No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 

我只是想知道什麼可能是一個更好的方式來完成這項任務。

+0

在這裏看到:http://stackoverflow.com/a/10410159/1025391 – moooeeeep

+0

其他可能重複:http://stackoverflow.com/q/2342162/1025391 – moooeeeep

回答

1

也如在this rather similar question中討論的那樣,可以使用Boost Format Library。例如:

std::string PrintMyMessage(const string& currentValAsString) 
{ 
    boost::format fmt = boost::format("Current value is %s") % currentValAsString; 
    // note that you could directly use cout: 
    //std::cout << boost::format("Current value is %s") % currentValAsString; 
    return fmt.str(); 
} 

在另一個問題的答案中,您還可以找到其他方法,例如,使用stringstreams,snprintf或字符串連接。

下面是一個完整的通用例子:

#include <string> 
#include <iostream> 
#include <boost/format.hpp> 

std::string greet(std::string const & someone) { 
    boost::format fmt = boost::format("Hello %s!") % someone; 
    return fmt.str(); 
} 

int main() { 
    std::cout << greet("World") << "\n"; 
} 

或者,如果您不能或不想使用升壓:

#include <iostream> 
#include <string> 
#include <vector> 
#include <cstdio> 

std::string greet(std::string const & someone) { 
    const char fmt[] = "Hello %s!"; 
    std::vector<char> buf(sizeof(fmt)+someone.length()); 
    std::snprintf(&buf[0], buf.size(), fmt, someone.c_str()); 
    return &buf[0]; 
} 

int main() { 
    std::cout << greet("World") << "\n"; 
} 

兩個例子產生下面的輸出:

$ g++ test.cc && ./a.out 
Hello World! 
+0

看起來不錯的選擇。 :) –

+0

這是如何工作的? valist? – Dennis

+0

[總而言之,格式類將格式字符串(最終具有類似printf的指令)轉換爲內部流上的操作,最後將格式化結果作爲字符串或直接返回到輸出流中。] (http://www.boost.org/doc/libs/1_49_0/libs/format/doc/format.html#how_it_works) – moooeeeep

0
string PrintMyMessage(const string& currentValAsString) 
{ 
    char buff[100]; 
    sprintf(buff, "Current value is %s", currentValAsString.c_str()); 

    return buff; 
} 
-2

你可以簡單地寫這個:

return "Current value is " + currentValAsString; 
0
string PrintMyMessage(const char* fmt, ...) 
{ 
    char buf[1024]; 
    sprintf(buf, "Current value is "); 

    va_list ap; 
    va_start(ap, fmt); 
    vsprintf(buf + strlen(buf), fmt, ap); 

    return buf; 
} 

string str = PrintMyMessage("Port is %d, IP is :%s", 80, "192.168.0.1"); 
+0

你應該使用'= {0}'初始化你的緩衝區,並且有一個vsnprintf模板用於確保緩衝區不被溢出。 – Dennis

+0

你是對的,實際上,1024大小的緩衝區可能是一個潛在的bug :) – Aladdin