【问题标题】:Read and write int pairs from file从文件中读取和写入 int 对
【发布时间】:2015-07-12 11:11:10
【问题描述】:

我正在尝试从文件中读取和写入一系列 int 对。该文件看起来像这样:

0 6
12 24
48 33
23 24
80 79

我的目标是将每一对读入一个结构:

struct foo {
    int a;
    int b;
}

然后将每个结构压入堆栈。然而,事实证明,fstreams 很难处理这个任务。现在,我的文件读取代码如下所示:

std::fstream fileStream(file, std::ios::in);
int a, b;
while (fileStream >> a >> b) {
    myStack.push({ a, b });
}

我的输入可能看起来像这样(我必须单独完成,因为我正在使用它......):

inputFoo(foo bar) {
    std::fstream fileStream(file, std::ios::out);
    fileStream << bar.a << " " << bar.b;
}

但是,我觉得这不是我应该有效和安全地执行此操作的方式。我还有一个检查文件是否已经存在的函数,但我不确定它是否有效:

bool fileExists() {
    std::ifstream stream;
    return stream.good();
}

真正做到这一点的最佳方法是什么?

【问题讨论】:

标签: c++ file input stream output


【解决方案1】:

这样做

std::ifstream fileStream(file, std::ios::in);

while (!fileStream.eof()) {
    foo f;
    fileStream >> f.a>> f.b
    myStack.push(f);
}

循环将结束读取整个文件

写作会是这样的

std::ofstream fileStream(file, std::ios::in);

while (!myStack.isEmpty()) {
    foo f;
    f=myStack.pop();
    fileStream << f.a<<" "<< f.b<<endl;

}

【讨论】:

  • 谢谢!将 foos 写入文件怎么样?
  • f=myStack.pop(); - std::stack::pop()std::vector::pop() 返回 void
  • 这是什么LogicStuff?
【解决方案2】:

您不需要fileExists() 函数。该函数中的流甚至没有打开。像这样检查:

std::fstream fileStream(file, std::ios::in);

if(!fileStream.is_open())
{
    // handle the error
}

现在,如果您愿意,有一些建议不会改变逻辑:

  • 使用std::ifstream 作为输入,您可以省略std::ios::in 参数
  • 使用std::ofstream 输出,您可以省略std::ios::out 参数
  • 重载foo&lt;&lt;&gt;&gt; 运算符:

    struct foo
    {
        int a;
        int b;
    
        foo() : a(0), b(0) {} // default constructor to make it a little more c++ and less c
    
        friend std::istream &operator>>(std::istream &is, foo &f);
    
        std::ostream &operator<<(std::ostream &os)
        {
            return os << a << " " << b;
        }
    };
    
    // Both can be friend, only operator<< can be member
    std::istream &operator>>(std::istream &is, foo &f)
    {
        return is >> f.a >> f.b;
    }
    

    您不仅可以向其传递文件流,还可以向其传递例如std::cinstd::cout(可能对调试和控制台输入输出有用)。你会这样读:

    foo f;
    
    while(fileStream >> f)
        myStack.push(f);
    

    写得更简单:

    fileStream << bar;
    

至于你的评论,这是我唯一想到的:

const std::string filePath = "file.txt";
std::ifstream ifs(filePath);

if(ifs.is_open())
{
    // read
}
else
{
    std::ofstream ofs(filePath);

    // write
}

【讨论】:

  • 谢谢!关于文件存在的一个问题:如果文件存在,我想做的是读取文件,如果文件不存在,则创建/开始写入文件。我将如何使用 fstream.open() 呢?
  • 我面临的一个问题:当我执行 fileStream >> f 时,它给了我一个错误:没有找到采用 std::ifstream 类型的左手操作数的运算符(或者没有可接受的转换)。我实现了 foo 运算符重载,它与 ofstream 一起工作,但 ifstream 给它带来了问题。有解决办法吗?
  • 好的,很抱歉出现这些问题,但现在我遇到了一堆无法理解的 LNK2005 错误。这似乎源于朋友类。不过,我认为到目前为止我还没有定义任何重复的运算符重载。
  • @user3760657 仍然显示它们。
  • 我很抱歉,没关系,我能够通过将朋友类的定义移动到 cpp 文件而不是 .h 文件来修复它。我的错误,现在一切正常。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多