首页 > 解决方案 > 为什么在这种情况下 seekp() 失败?

问题描述

我正在使用这个程序来修改 text.txt 中的每个元音以成为主题标签('#')

#include <fstream>
#include <iostream>

int main()
{
    std::fstream iofile{ "text.txt", std::ios::in | std::ios::out };

    char chChar;

    while (iofile.get(chChar))
    {
        switch (chChar)
        {
        case 'a':
        case 'e':
        case 'i':
        case 'o':
        case 'u':
        case 'A':
        case 'E':
        case 'I':
        case 'O':
        case 'U':

            iofile.seekp(-1, std::ios::cur);

            iofile << '#';

            iofile.seekg(iofile.tellg(), std::ios::beg); 
        }
    }
}

所以如果 text.txt 的初始内容是

something is funny

它会变成

s#m#th#ng #s f#nny

问题是这条线

iofile.seekg(iofile.tellg(), std::ios::beg); 

这一行将文件指针保持在同一位置,所以我想我可以将这一行更改为

iofile.seekg(0, std::ios::cur);

我认为这会做同样的事情,但事实并非如此。当我运行程序时,控制台就停在那里并且没有停止,并且 text.txt 开始打印奇怪的东西。但是当我用这条线替换它时,它又可以工作了

iofile.seekg(1, std::ios::cur);

我认为这应该将文件指针移动得太远(我们应该将它保持在原位,但在这里我们将它移动通过 1 个字母)。但是,这行得通。怎么了?

标签: c++filefile-pointer

解决方案


iofile << '#';
iofile.flush();  // flush buffer when switching from output to input
iofile.seekg(0, std::ios::cur);

我最近正在阅读一本关于 iostream 的书,“Standard C++ IOStreams and Lcocales”。该书在第 1.4.3 节“双向文件流:从输出切换到输入”中进行了描述,

当输出已写入双向文件流时,在写入文件流后立即尝试读取将导致“未定义结果”。.... .... 读取操作可能会失败,但无论如何都不会指示此失败;

作者提到写后读前必须先flush流,还有写的是调用seekg(0, ios_base::beg)有清空内部缓冲区的效果,但是不确定seekg()在像 ios_base::cur 这样的第二个参数上使用不同的值调用也可以。


推荐阅读