【问题标题】:How to create a string with format specifier? [duplicate]如何使用格式说明符创建字符串? [复制]
【发布时间】:2012-06-11 09:49:15
【问题描述】:

我想创建一个公共 api,它接受一个字符串作为参数,并将这个字符串放在我在该 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

我只是想知道什么是完成这项任务的更好方法。

【问题讨论】:

标签: c++ string


【解决方案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";
}

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

#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!

【讨论】:

【解决方案2】:
string PrintMyMessage( const string& currentValAsString)
{
    char buff[100];
    sprintf(buff, "Current value is %s", currentValAsString.c_str());

    return buff;
}

【讨论】:

    【解决方案3】:
    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}初始化你的缓冲区,并且有一个vsnprintf模板用于确保缓冲区没有溢出。
    • 你是对的,实际上,1024 大小的缓冲区可能是一个潜在的错误:)
    【解决方案4】:

    你可以这么写:

    return  "Current value is " + currentValAsString;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-03
      • 1970-01-01
      • 2011-06-19
      • 2020-11-22
      • 2020-10-08
      • 2020-12-14
      • 1970-01-01
      相关资源
      最近更新 更多