String.Format alternative in C++
本文关键字:C++ in alternative Format String | 更新日期: 2023-09-27 18:33:05
我没有太多与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
作为a
、b
和c
参数。任何建议如何生成这些格式化字符串以传递给程序中的系统?
> C++方法是将std::stringstream
对象用作:
std::stringstream fmt;
fmt << a << " " << b << " > " << c;
C 方法是使用 sprintf
.
C 方法很难正确,因为:
- 类型不安全
- 需要缓冲区管理
当然,如果性能是一个问题,你可能希望回到 C 方式(假设您正在创建固定大小的百万小stringstream
对象,然后将它们丢弃)。
为了完整起见,您可以使用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";
}
供参考:
- http://en.cppreference.com/w/cpp/string/basic_string/operator+
如果你真的想走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";
}
供参考:
- http://en.cppreference.com/w/cpp/io/c/fprintf
从 C++11 开始,您可以将其"简化"为:
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
int main() {
std::string a = "a", b = "b", c = "c";
const char fmt[] = "%s %s > %s";
// can use std::string as buffer directly (since C++11)
std::string::size_type size = 256;
std::string str;
do {
str.resize(size+1);
// 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
size = std::snprintf(
&str[0], str.size(),
fmt, a.c_str(), b.c_str(), c.c_str());
} while (size+1 > str.size());
// can strip off null-terminator, as std::string adds their own
str.resize(size);
// done
std::cout << str << "'n";
}
供参考:
- 直接写入 std::string 的 char* 缓冲区
然后,是Boost格式库。为了您的示例:
#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";
}
除了其他人建议的选项之外,我还可以推荐 fmt 库,它实现了类似于 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);
免责声明:我是这个库的作者。
sprintf
与std::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() );
为了完整性,提升方法是使用boost::format
cout << boost::format("%s %s > %s") % a % b % c;
任你挑选。boost解决方案具有sprintf
格式的类型安全优势(对于那些发现<<
语法有点笨拙的人)。
如前所述,C++方法是使用字符串流。
#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();
您只需连接字符串并构建命令行即可。
std::string command = a + ' ' + b + " > " + c;
system(command.c_str());
为此,您不需要任何额外的库。