我试图编写一个程序,用' x'来替换特定的数字。字符。该任务要求每个数字都在自己的行中,但它似乎是' \ n'导致读/写指针表现出这个世界。 Here's a picture of the output。 我的问题是: 为什么指针表现如此? 我需要向后移动写指针以覆盖一行以使其工作? 是否有更简单的解决方法?
这是我的代码:
void input(int n)
{
fstream file;
file.open("numbers.txt", ios::out);
while(n --> 0)
{
file << n;
file << '\n';
}
file.close();
}
void read()
{
fstream file;
string tmp;
file.open("numbers.txt", ios::in);
while(true)
{
getline(file,tmp);
if(file.eof())
break;
cout << tmp << endl;
cout << "tellg: " << file.tellg() << " tellp: " << file.tellp() << endl;
}
file.close();
}
void replace()
{
fstream file;
string tmp;
file.open("numbers.txt", ios::in | ios::out);
while(true)
{
file >> tmp;
if(tmp == "6")
{
//cout << file.tellg() << endl;
file.seekp(file.tellg() - tmp.length()-1);
file << "x";
}
if(file.eof())
break;
}
file.close();
}
int main()
{
input(10);
replace();
read();
return 0;
}
答案 0 :(得分:1)
由于您以文本模式打开文件,因此需要考虑底层流可能使用行结束序列(\r\n
)而不仅仅是\n
的可能性。我想,这是主要问题。最简单的补救措施是以二进制模式打开文件:
file.open("numbers.txt", std::ios_base::binary | std::ios_base::in | std::ios_base::out);
也就是说,由于你在没有干预寻求的情况下从写入切换到阅读,你的代码是未定义的行为,即任何事情都可能发生。你应该在写作和阅读之间寻找当前的位置。
就个人而言,我不会在原地重写文件。它通常是不必要的技巧。如果我要重写文件,我会使用seekg()
在读取之前获取当前位置,保存位置并在写入之前恢复它(我基本上从不使用搜索操作,即我可能签名错了):
for (std::streampos pos = (in >> std::ws).tellg();
in >> tmp; pos = (in >> ws).tellg()) {
if (need_to_overwrite) {
in.seekp(pos);
// ...
in.seekg(0, std::ios_base::cur);
}
}
使用in >> std::ws
是为了确保在存储位置之前跳过空格。
另请注意,您对file.eof()
的检查是错误的:最后一行会被处理两次。从文件中读取时,应在使用读取字符串之前测试结果,例如:
while (in >> tmp) {
// ...
}