【问题标题】:C++ fstream read and write positions not alignedC ++ fstream读写位置未对齐
【发布时间】:2020-10-24 03:42:48
【问题描述】:

我正在编写一个程序来在文件中搜索一个名称,然后覆盖该名称后面的一些数字。我目前的方法是从fstream 读取直到找到名称,然后使用相同的fstream 覆盖该点之后的数字。但是,光标位置似乎错误。这是一个测试程序:

#include <fstream>
#include <iostream>

int main() {
    std::string name;
    std::fstream file("test.txt", std::fstream::in | std::fstream::out);
    while (file >> name) {
        if (name == "Jason") {
            file << "A";
            break;
        }
    }
    file.close();
}

当 test.txt 只包含一行时,输出似乎是正确的; 'A' 就在'Jason' 之后

test.txt:

                      Jason -1395354120                    0

结果:

                      JasonA-1395354120                    0

但是,当有多行时,'A' 会被写入数字的中间:

test.txt:

                      Jason -1395354120                    0
                        Bob  1266020048                    0
                      Jason -1395354120                    0
                        Bob  1266020048                    0
                      Jason -1395354120                    0
                        Bob  1266020048                    0

结果:

                      Jason -139A354120                    0
                        Bob  1266020048                    0
                      Jason -1395354120                    0
                        Bob  1266020048                    0
                      Jason -1395354120                    0
                        Bob  1266020048                    0

我希望它总是写在名字之后。我该如何解决这个问题?

编辑:如果我将 file &lt;&lt; "A"; 替换为 std::cout &lt;&lt; file.tellg() &lt;&lt; " " &lt;&lt; file.tellp() &lt;&lt; std::endl;,则表明写入和读取位置都在 37,这是第二个示例中 A 出现的位置。我对此感到困惑,因为我认为 >> 运算符应该在“Jason”之后停止阅读,应该是 31。

【问题讨论】:

    标签: c++ file-io fstream


    【解决方案1】:

    您可以使用 seekg() 函数从某个位置开始:

    file.seekg(5, ios::beg); 
    //The first parameter is the position, second is you are specifying if it is the beginning or end 
    

    【讨论】:

    • 我想搜索一个可能不知道行号的名称,所以无论如何我都需要阅读该文件。我认为 >> 运算符在空格处停止,那么为什么在我的示例中不这样做呢?
    • 看起来只是在文件末尾添加了“A”。
    【解决方案2】:

    Jason,我尝试了你的代码,但它给了我不同的结果:

    test.txt:

     Jason -1395354120                    0
    

    结果:

     Jason -1395354120                    0
    A
    

    test.txt:

     Jason -139A354120                    0
       Bob  1266020048                    0
     Jason -1395354120                    0
       Bob  1266020048                    0
     Jason -1395354120                    0
       Bob  1266020048                    0
    

    结果:

     Jason -139A354120                    0
       Bob  1266020048                    0
     Jason -1395354120                    0
       Bob  1266020048                    0
     Jason -1395354120                    0
       Bob  1266020048                    0
    A
    

    换句话说,代码没有找到“Jason”,只是在末尾添加了“A”。也许您可以尝试在条件中包含file &lt;&lt; "A"; 命令,以查看程序是如何工作的

    编辑:这对我有用:

    while (name != "Jason")
        {
            if (!(file >> name))
            {
                break;
            }
        }
    

    【讨论】:

    • 嗯...对我来说,它没有在末尾添加 A。我用std::cout &lt;&lt; file.tellg() &lt;&lt; " " &lt;&lt; file.tellp() &lt;&lt; std::endl; 替换了file &lt;&lt; "A";,可以看到第二个例子的读写位置都是37。
    • 我认为问题在于while循环最后一次执行file &gt;&gt; name命令来检查条件。我的建议是在while 条件中仅保留name != "Jason",在正文中保留file &gt;&gt; name。您还需要检查文件的结尾并添加break; 命令以退出循环。
    • 我改了代码来检查循环体内的匹配,但结果还是一样。
    • 我用一个(至少对我而言)按预期工作的解决方案编辑了我上面的答案,无论是单行输入还是多行输入。
    猜你喜欢
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 2014-09-15
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    • 1970-01-01
    相关资源
    最近更新 更多