将所有printf输出到内存变量中。printf转string

本文介绍了一种在C++中将printf输出重定向至字符串的方法,通过定义宏和辅助函数,可以轻松地将所有格式化的输出内容收集并保存在std::string变量中,便于进一步的数据处理或展示。

在一般coding时,会使用非常多的printf,格式化输出到命令行来显示,但如果有一天希望将格式化输出的内容不输出到命令行,而是保存到一个字符串string变量里,供其他代码使用。这时,最好的方式不是一个一个去修改printf,而是用下面的方式:


void functionA()
{
。。。
printf( "%06x:", ((u1*)insns - pDexFile->baseAddr) + insnIdx*2);
。。。
printf(" %02x%02x", bytePtr[0], bytePtr[1]);
。。。
printf("     ");
。。。
brintf("|%04x: nop // spacer", insnIdx);
。。。
}



希望将上面的printf所有内容保存到变量std:string allInfo中,修改为:


std::string & std_string_format(std::string & _str, const char * _Format, ...) {  
	std::string tmp;  


	va_list marker = NULL;  
	va_start(marker, _Format);  


	size_t num_of_chars = _vscprintf(_Format, marker);  


	if (num_of_chars >= tmp.capacity()) {  
		tmp.resize(num_of_chars + 1);  
	}  


	vsprintf_s((char *)tmp.data(), tmp.capacity(), _Format, marker);  


	va_end(marker);  


	_str = tmp.c_str();  
	return _str;  
}  


void functionA()
{
#define PRINT(_FORMATE, ...)  allInfo += std_string_format(info, _FORMATE, ##__VA_ARGS__);//printf("%s", info.c_str());
#define printf(_FORMATE, ...) PRINT(_FORMATE, ##__VA_ARGS__)
std::string info,allInfo;


。。。
printf( "%06x:", ((u1*)insns - pDexFile->baseAddr) + insnIdx*2);
。。。
printf(" %02x%02x", bytePtr[0], bytePtr[1]);
。。。
printf("     ");
。。。
printf("|%04x: nop // spacer", insnIdx);
。。。


#undef printf
}


什么都不用动,只要在functionA中加4行代码即可。前面2行宏和1行变量定义,后面1行undef,这样,就会将printf输出的所有内容保存到变量allInfo中。


在C++中,`printf`函数是C语言标准库中的函数,它不支持直接输出`std::string`类型的变量。`printf`的格式化字符串参数要求传入的是基本数据类型的指针或值,而`std::string`是一个类类型,直接使用`%s`格式化说明符传入`std::string`变量会导致未定义行为,通常表现为输出乱码或程序崩溃[^1]。 要使用`printf`输出`std::string`变量,必须将其换为C风格的字符串,即`const char*`类型。`std::string`类提供了`c_str()`成员函数,该函数返回一个指向以空字符结尾的字符数组的指针,该数组包含字符串的当前值。通过调用`c_str()`函数,可以将`std::string`对象换为`printf`可接受的格式。 以下是一个示例代码: ```cpp #include <iostream> #include <cstdio> #include <string> int main() { std::string s = "Hello"; s += "!"; // 使用 c_str() 将 std::string 换为 const char* 以供 printf 使用 std::printf("%s\n", s.c_str()); // 正确输出 "Hello!" } ``` 在上述代码中,`s.c_str()`返回一个`const char*`指针,指向`std::string`对象内部的字符数组。`printf`函数通过`%s`格式说明符正确地读取并输出该字符串内容[^3]。 需要注意的是,`c_str()`返回的指针是临时的,其有效性在下一次对字符串对象的非常量成员函数调用之前或该字符串对象被销毁之前有效。因此,在使用`printf`输出后,如果对`std::string`对象进行了修改,再次调用`c_str()`是必要的。 此外,虽然`printf`在C++中仍然可用,但推荐使用C++标准库提供的`std::cout`进行输出,因为`std::cout`支持`std::string`的直接输出,无需进行类型换,并且具备类型安全性和更好的可读性。 ### 相关问题 1. 如何在C++中使用`std::cout`输出`std::string`变量? 2. `std::string::c_str()`函数的作用是什么? 3. `printf`与`std::cout`在C++字符串输出中的区别是什么? 4. 为什么不能直接使用`printf`输出`std::string`变量? 5. `std::string`对象的生命周期对`c_str()`返回的指针有何影响?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值