C++ 为什么这篇文章写的是垃圾?

C++ 为什么这篇文章写的是垃圾?,c++,string,fwrite,C++,String,Fwrite,我正在构建一个程序,它接收串行数据并将其保存到文件中。每行数据都有时间戳。在这段代码中,数据的时间戳行是s string s = get_timestamp(); cout << "input string named s is: " << s << "\n"; numChars = sizeof(s); cout << "size is: " << numChars << "\n"; fwrite( &s,

我正在构建一个程序,它接收串行数据并将其保存到文件中。每行数据都有时间戳。在这段代码中,数据的时间戳行是s

string s = get_timestamp();
cout << "input string named s is: " << s << "\n";  
numChars = sizeof(s);
cout << "size is: " << numChars << "\n"; 
fwrite( &s, sizeof(char) , numChars , DATA_LOG);
您可以看到,由于某种原因,“名为s的输入字符串”似乎被覆盖。但这并不是我真正关心的问题(尽管我不知道为什么会发生这种情况)


我的主要问题是我的fwrite将垃圾保存到文件中。您可以看到numChars和string是正确的。我尝试过用同样的垃圾结果替换“&s”、“static_cast&s”。有什么想法吗?

首先,我怀疑
s
包含一些想法。这会导致光标移动行的开头,进一步的输出会覆盖已打印的内容。要查看打印的实际字符,请将程序的输出重定向到文件,然后使用十六进制编辑器/查看器(例如)检查结果

其次,
sizeof(s)
不是确定
std::string
长度的正确方法。改用
s.length()
。这就是为什么
numChars
不正确的原因

最后,要将字符串写入文件,请使用:

fwrite( s.data(), sizeof(char) , s.length() , DATA_LOG);
sizeof(s)
实际上应该是
strlen(s)
wcslen(s)

或者,如果您使用的是
std::basic_string
.length()
将为您提供长度,
.c_str()
将为您提供
字符字符串指针,而不是指向实际对象的
&s

所以试试看:

if(!s.empty()){
    fwrite(s.c_str(), sizeof(s.front()), s.length(), DATA_LOG);
}

std::string s
写入一个文件将如下所示:

fwrite(s.c_str(), 1, s.size(), DATA_LOG); 

查看控制台打印输出时,您的数据可能存在其他问题,但如果没有在调试器或类似工具中看到实际数据,我不确定

我们是否要为该标准设置数据日志?您熟悉术语“缓冲io”吗?
s
的类型是什么?请指定它运行的操作系统,因为POSIX、Windows和MacOS有不同的换行约定。这是您的问题<应用于
std::string
对象的code>sizeof
,与字符串中存储的字符数无关。写入文件的是
std::string
对象的内容,而不是它管理的字符序列。“换行符”在不同的操作系统中也不同。请在每行末尾使用“\r\n”以防万一。@Roboprog:以防万一?为什么要将
“\r\n”
写入仅使用
“\n”
作为行终止符的系统上的文件?如果文件是以文本模式打开的,
fwrite
会将数据中的任何换行符转换为系统的行尾表示形式。@KeithThompson:因此,无论您通过“cat”或“type”在哪个操作系统上查看文件,光标都会移到左边距并删除一行。文本模式应该会处理它,但偏执狂可能会有用。@Roboprog:因此,您在Unix系统上生成的文本文件在每行末尾都有一个无关的
'\r'
字符。如果在Windows上运行,正常的文本模式处理将导致每一行以
“\r\r\n”
结尾
cat
type
可能没有问题,但其他工具会有问题
grep'foo$'file.txt
永远不会匹配,因为
foo
永远不会在一行的末尾(后面总是跟着
\r
)。@MooingDuck:你的意思是查找字符串基类型的大小吗?sizeof(s[0])在这种情况下?
sizeof(s)
,即
sizeof(std::string)
,是不相关的。(请注意,
std::string
对象的大小不会随着其管理的字符序列长度的变化而变化;它都是内部簿记数据。)
fwrite(s.c_str(), 1, s.size(), DATA_LOG);