【问题标题】:Writing using << on an fstream在 fstream 上使用 << 编写
【发布时间】:2012-12-14 12:25:09
【问题描述】:

我正在尝试使用 c++ fstream 类将long 写入文本文件。该文件在执行之前已经在磁盘上创建。我运行以下代码,可以读取初始值但无法保存新值,覆盖。我做错了什么?

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>


using namespace std;

int main(int argc, char* argv[]) {

    long f;

    fstream myFile("data.txt", fstream::in|fstream::out);
    cout << "f before: " << f << endl;
    myFile >> f;
    cout << "f after: " << f << endl;
    f++;
    cout << "f after increment: " << f << endl;

    myFile << f;
    myFile.close();

    return 0;
}

之后,我读取了文件中的值并且它没有改变。我在这里做错了什么?

【问题讨论】:

  • 首先将'f'初始化为0。您正在写新的 f 旧的之后,而不是在同一个地方。

标签: c++ file fstream


【解决方案1】:

在写入之前,您需要倒退到文件的开头。否则,第二个值将写在第一个值之后。

【讨论】:

  • 如果是这样的话,不应该把新的内容写到文件末尾吗?如果不是,为什么?
  • @ThiagoMoraes:假设数字是文件包含的唯一内容,是的。事实上,当我运行你的代码时,这正是发生的事情。
  • 在我的系统上,这仅发生在 2 次运行中。之后,文件没有更新。为了让它始终工作,我们需要清除错误状态。更新了我的答案。
  • 不幸的是,这里没有发生。当我按照凯文的回答关闭并重新打开文件时,它可以工作,但我不明白这是否需要。
【解决方案2】:

您需要在myFile &lt;&lt; f; 之前添加myFile.seekp(ios::beg); 才能正确更新计数。

如果要继续追加到末尾,请在myFile &lt;&lt; f; 之前添加myFile.clear();。这将导致内容变为: 1->12->1213->12131214->1213121412131215。这是必需的,因为在读取输入时会达到 eof。请注意,get 和 put 指针是same

正如您正确指出的那样,这是必需的,因为文件只有数字,甚至没有换行符。因此,读取操作直接命中 EOF 并导致问题。为了解决它,我们清除 eof 状态并继续。

按照您的建议,在末尾添加换行符是一种解决方案。在那种情况下

myFile.seekp(ios::beg);
myFile << f<<"\n";

将是完整的解决方案。

【讨论】:

  • 只是重复上面的评论:如果是这种情况,不应该将新内容写入文件末尾吗?如果不是,为什么?
  • @ThiagoMoraes 更新了,看看。
  • 嗯,你回答了,我没看到。我的代理人不允许我将答案标记为正确,所以我道歉或那样做。谢谢!
【解决方案3】:

我发现我在这里做错了:

我的文件只包含我以后想读和写的长度。当我阅读文件时,我到达了 EOF,然后无法倒带或在最后写入任何内容。

也就是说,我的解决方案是在文件末尾包含一个空格或 \n。

有人知道为什么 API 会这样工作吗?对我来说似乎不是很有用...

【讨论】:

  • >> 运算符一直读到换行符。如果它读取任何它无法理解的内容,则设置失败位。这正是您需要在编写之前调用 clear() 的原因。此外,您可能需要编辑您的问题以包含此内容。
【解决方案4】:

这与这一行有关:

我的文件 >> f;

删除它,一切正常。我对 fstream 不熟悉,但在我看来,这段代码会试图强制一个长字符串。我也不允许将其投射到很长,这让我认为这永远不会像这样执行。我建议您阅读如何从文件中检索长类型的值,然后再试一次。

编辑:
在阅读了一点this 站点建议您必须在读写之间关闭并重新打开文件后,我很惊讶它实际上已修复。我不禁想知道为什么,我认为 fstream 是用于阅读或写作或两者兼而有之的......无论如何,这是你的工作代码:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char* argv[]) {

    long f;

    fstream myFile("data.txt", fstream::in|fstream::out);
    cout << "f before: " << f << endl;
    myFile >> f;
    cout << "f after: " << f << endl;
    f++;
    cout << "f after increment: " << f << endl;
    myFile.close();
    myFile.open("data.txt", fstream::in|fstream::out);

    myFile << f;
    myFile.close();

    return 0;
}

【讨论】:

  • -1:线路没有问题; 正是你应该如何从(格式化的)流中获取long
  • 正如我所说,我不熟悉 fstream,但如果我删除该行,我可以写入文件,而当我保留该行时,我无法写入文件。不知道为什么我被否决了,因为我没有说过任何不真实的话。
  • 好吧,你说“在我看来,这段代码会尝试强制一个长字符串”和“这绝不是这样执行的。我建议你阅读如何检索文件中的值作为长类型。”这使您的(原始)答案具有误导性,因为myFile &gt;&gt; f; “从文件中检索长类型值”的正确方法。
  • 似乎再次打开文件有效。对于我的实际情况,这不是一个理想的解决方案,但可以解决这个特定问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-15
  • 1970-01-01
  • 1970-01-01
  • 2016-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多