C ++中的String.Format替代品

时间:2012-05-02 08:15:26

标签: c# c++ string string-formatting

我没有太多使用C ++的经验。相反,我在C#中工作得更多,所以,我想问一下我在那里会做些什么。我必须生成一个特定的字符串格式,我必须传递给另一个函数。在C#中,我可以通过以下简单代码轻松生成字符串。

string a = "test";
string b = "text.txt";
string c = "text1.txt";

String.Format("{0} {1} > {2}", a, b, c);

通过生成上述字符串,我应该能够在system()中传递它。但是,system仅接受char*

我在Win32 C++(不是C ++ / CLI),并且不能使用boost,因为它包含太多包含项目本身非常小的所有文件。 sprintf()之类的内容对我很有用,但sprintf不接受string abc参数。有关如何生成这些格式化字符串以在程序中传递给系统的任何建议吗?

7 个答案:

答案 0 :(得分:33)

C ++的方式是使用std::stringstream对象:

std::stringstream fmt;
fmt << a << " " << b << " > " << c;

C方式是使用sprintf

C方式很难做到:

  • 类型不安全
  • 需要缓冲管理

当然,如果性能是一个问题,你可能想要退回到C路上(假设您正在创建固定大小的百万个stringstream个小对象,然后将它们扔掉)。

答案 1 :(得分:19)

为了完整起见,您可以使用std::stringstream

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::string a = "a", b = "b", c = "c";
    // apply formatting
    std::stringstream s;
    s << a << " " << b << " > " << c;
    // assign to std::string
    std::string str = s.str();
    std::cout << str << "\n";
}

或者(在这种情况下)std::string有自己的字符串连接功能:

#include <iostream>
#include <string>

int main() {
    std::string a = "a", b = "b", c = "c";
    std::string str = a + " " + b + " > " + c;
    std::cout << str << "\n";
}

供参考:


如果你真的想要走C路。你在这里:

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

int main() {
    std::string a = "a", b = "b", c = "c";
    const char fmt[] = "%s %s > %s";
    // use std::vector for memory management (to avoid memory leaks)
    std::vector<char>::size_type size = 256;
    std::vector<char> buf;
    do {
        // use snprintf instead of sprintf (to avoid buffer overflows)
        // snprintf returns the required size (without terminating null)
        // if buffer is too small initially: loop should run at most twice
        buf.resize(size+1);
        size = std::snprintf(
                &buf[0], buf.size(),
                fmt, a.c_str(), b.c_str(), c.c_str());
    } while (size+1 > buf.size());
    // assign to std::string
    std::string str = &buf[0];
    std::cout << str << "\n";
}

供参考:


然后,有Boost Format Library。为了你的例子:

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

int main() {
    std::string a = "a", b = "b", c = "c";
    // apply format
    boost::format fmt = boost::format("%s %s > %s") % a % b % c; 
    // assign to std::string
    std::string str = fmt.str();
    std::cout << str << "\n";
}

答案 2 :(得分:13)

除了其他人建议的选项之外,我还可以推荐fmt library,它实现类似于Python中的str.format和C#中的String.Format的字符串格式。这是一个例子:

std::string a = "test";
std::string b = "text.txt";
std::string c = "text1.txt";
std::string result = fmt::format("{0} {1} > {2}", a, b, c);

免责声明:我是这个图书馆的作者。

答案 3 :(得分:6)

您可以将sprintfstd::string.c_str()结合使用。

c_str()返回const char*并与sprintf合作:

string a = "test";
string b = "text.txt";
string c = "text1.txt";
char* x = new char[a.length() + b.length() + c.length() + 32];

sprintf(x, "%s %s > %s", a.c_str(), b.c_str(), c.c_str() );

string str = x;
delete[] x;

如果您知道尺寸,则可以使用预先分配的char数组:

string a = "test";
string b = "text.txt";
string c = "text1.txt";
char x[256];

sprintf(x, "%s %s > %s", a.c_str(), b.c_str(), c.c_str() );

答案 4 :(得分:2)

为了完整起见,提升方式是使用boost::format

cout << boost::format("%s %s > %s") % a % b % c;

接受你的选择。增强解决方案具有sprintf格式的类型安全优势(对于那些发现<<语法有点笨拙的人来说)。

答案 5 :(得分:2)

您可以连接字符串并构建命令行。

std::string command = a + ' ' + b + " > " + c;
system(command.c_str());

您不需要任何额外的库。

答案 6 :(得分:1)

如前所述,C ++方式正在使用stringstreams。

#include <sstream>

string a = "test";
string b = "text.txt";
string c = "text1.txt";

std::stringstream ostr;
ostr << a << " " << b << " > " << c;

请注意,您可以像这样从字符串流对象中获取C字符串。

std::string formatted_string = ostr.str();
const char* c_str = formatted_string.c_str();