找到你要的答案

Q:Read and write int pairs from file

Q:读和写int对文件

I'm trying to read and write a sequence of int pairs from a file. The file would look something like this:

0 6
12 24
48 33
23 24
80 79

My goal is to read each pair into a struct:

struct foo {
    int a;
    int b;
}

And then push each struct into a stack. However, fstreams have proven rather difficult to handle for this task. Right now, my file read code looks like this:

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

And my input might look like this (I have to do it individually because of what I'm using it for...):

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

However, I have a feeling this isn't how I should be efficiently and safely doing this. I also have a function that checks if the file exists already, but I'm not sure that one works either:

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

What's the best way to actually do this?

我试图读写一个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();
}

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

answer1: 回答1:

You don't need fileExists() function. The stream in that function was not even open. Just check like this:

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

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

Now, if you'd like, there are few suggestions that don't change the logic:

  • use std::ifstream for input and you can omit the std::ios::in argument
  • use std::ofstream for output and you can omit the std::ios::out argument
  • overload << and >> operators of foo:

    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;
    }
    

    to which you can pass not only file streams, but for example std::cin and std::cout (might be useful for debugging and console input-output). You'll read like this:

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

    And write even simpler:

    fileStream << bar;
    

As to your comment, this is the only thing that comes to my mind:

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

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

    // write
}

你不需要fileexists()功能。该函数中的流甚至没有打开。就这样检查:

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

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

现在,如果你愿意,很少有建议不要改变逻辑:

  • use std::ifstream for input and you can omit the std::ios::in argument
  • use std::ofstream for output and you can omit the std::ios::out argument
  • 超载<;<;和>;>;经营者foo:

    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::cin和std::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
}
answer2: 回答2:

do like this

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

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

loop will end of reading the entire file

Writing will be like this

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

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

}

这样做

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;

}
c++  file  input  stream  output