我有文件qwer.h
。它写在里面hello, misha
。我想在dear
后面加一个词hello
。
#include <iostream>
#include <fstream>
int main()
{
std::ofstream ff1{"qwer.h", std::ios::ate};
ff1.seekp(5, std::ios::beg);
ff1 << "dear" << std::endl;;
return EXIT_SUCCESS;
}
结果,在文件中qwer.h
我得到以下内容:^@^@^@^@^@dear
. 我尝试更改std::ofstream ff1{"qwer.h", std::ios::ate};
为std::ofstream ff1{"qwer.h", std::ios::ate | std::ios::app};
,但随后这些单词被简单地添加到文件末尾。
在这里您可以阅读有关流打开标志的信息: https ://en.cppreference.com/w/cpp/io/ios_base/openmode
如果您简要描述本质,那么它对
std::ios::app
您没有任何帮助,因为。设置此标志后,在每次写入操作之前,光标将设置到流的末尾,无论您之前将其移动到何处。std::ios::ate
还将光标在打开时设置到流的末尾,但在写入时不会将其移动到那里。由于您仅使用此标志打开流,因此程序不知道该流中已有哪些数据,因此,在ff1.seekp(5, std::ios::beg);
重新排列光标从开头开始的五个字符之后并在执行行之后ff1 << "dear" << std::endl;
用零填充前 5 个字符和覆盖其余部分。为了将文本粘贴到正确的位置,您需要添加标志
std::ios::in
,即 它应该看起来像这样:std::ofstream ff1{ "qwer.h", std::ios::in | std::ios::ate };
.这将允许程序获取流中已经存在的数据。虽然,总的来说,std::ios::ate
你甚至不需要它,因为。您从头开始计数,而不是从当前位置开始计数。因此,您可以像这样打开流:std::ofstream ff1{ "qwer.h", std::ios::in | std::ios::out };
. 该标志std::ios::out
允许写入流。但是,这仍然不会给你想要的结果,因为。您将保留流的前五个字符,然后将 4 个字符替换为 Dear 并显示流的其余部分。那些。你会得到类似的东西:Hellodearha
。为了在保留其余字符的同时插入新字符,使用临时流是最正确的,您将在其中完全形成所需的一切,然后将其复制到目标流。PS我希望我解释清楚:)