为什么将字符串输出到未命名的 std::ofstream 反而给了我一个十六进制数?
Why does output of a string to unnamed std::ofstream give me a hex number instead?
我试图将一些调试输出添加到 C++03 项目中,并得到了一些奇怪的结果。以下是简化的测试代码:
#include <fstream>
int main()
{
{
std::ofstream file("/tmp/test.txt");
file << "hello" << " ... OK, this worksn";
}
std::ofstream("/tmp/test.txt",std::ios_base::app) << "hello"
<< " ... no, I mean hello!n";
}
出于某种原因,这是我在编译后得到的:
$ g++ test.cpp -o test && ./test && cat /tmp/test.txt
hello ... OK, this works
0x80487fe ... no, I mean hello!
为什么在将字符串输出到未命名的对象时会得到一个十六进制数std::ofstream
?为什么第二个字符串的后续输出会起作用?
我们用于将 C 字符串传递给std::ostream
的常用operator<<
被声明为自由函数
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,
const char* s );
未命名的std::ofstream
对象是一个临时变量,临时变量不能绑定到非常量引用,因此此运算符重载不参与重载解析。取而代之的是采用最接近的匹配项,即成员函数
std::basic_ostream& std::basic_ostream::operator<<(const void*);
,它采用文字擦除的指针并仅打印其值。由于可以在对象是临时对象的情况下调用成员函数,因此这个函数确实可行。这解释了输出中的十六进制数。现在,此运算符返回一个引用,std::basic_ostream&
。由于这不再是一个临时对象,而是对一些非常量对象的引用,因此可以成功调用通常需要const char*
的operator<<
的自由函数重载。这就是按预期打印第二个字符串的原因。
请注意,从 C++11 开始,代码将按预期工作,因为那里我们有一个额外的重载operator<<
,它采用右值引用:
template< class CharT, class Traits, class T >
basic_ostream< CharT, Traits >& operator<<( basic_ostream<CharT,Traits>&& os,
const T& value );
,并且临时确实绑定到右值引用。
若要使代码在 C++03 中工作,可以使用成员函数std::ostream::flush()
,该函数返回对对象的非常量引用,并且对fstream
对象没有任何用户可见的副作用:
#include <fstream>
int main()
{
std::ofstream("/tmp/test.txt").flush() << "hello"
<< " ... OK, this now works toon";
}
相关文章:
- 将字符串转换为十六进制数组c++
- 如何使系统在十六进制数之前打印 0x,在八进制数之前打印 0?
- 将大十六进制数转换为十进制形式(以 10 为基数的形式)的算法
- 为什么将字符串输出到未命名的 std::ofstream 反而给了我一个十六进制数?
- 使用无符号字符数组输入十六进制数
- 将十六进制数作为主要函数参数
- 钻头和转移操作数以清除选定的十六进制数
- 在C/C++中将十六进制数组作为字符串写入文件
- 十六进制数组 cout 到文本文件失败
- 将十六进制数转换为布尔数组
- 在 C++,(C) 中更改十六进制数的前导零位
- 将十六进制数的 char[] 转换为对应于 ASCII 表中十六进制数字的字母的 char[] 并反转
- 如何获取十六进制数的最后 n 位数字
- 将char数组转换为十六进制数组(C++)
- 从几个十进制数中绘制一个十六进制数
- 如何使用十六进制数初始化字符数组
- 从十六进制数组读取 Int
- 从十六进制数组读取双精度到向量
- 试图输出命令行参数会产生一个看似随机的十六进制数
- 压缩一个十六进制数