c ++文件指针无法正常工作

时间:2016-05-28 20:14:18

标签: c++ file fstream

我试图编写一个程序,用' 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;
}

1 个答案:

答案 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) {
    // ...
}