3

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?

user3760657
  • 377
  • 3
  • 14
  • I'd use ifstream and ofstream instead of fstream – pjsofts May 02 '15 at 20:24
  • And for file existence if performance is an issue: http://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c – pjsofts May 02 '15 at 20:25

2 Answers2

4

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;

}
2

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
}
LogicStuff
  • 18,687
  • 6
  • 49
  • 70
  • Thanks! One question about the fileexists: What I want to do is read the file if it exists, and create / begin writing to the file if it doesn't exist. How would I use fstream.open() for that? – user3760657 May 02 '15 at 20:49
  • One problem I'm facing: when I do fileStream >> f, it gives me an error: no operator found which takes a left hand operand of type std::ifstream (or there is no accepable conversion). I implemented the foo operator overloading, and it works with the ofstream, but the ifstream gives it issues there. Is there a solution to this? – user3760657 May 02 '15 at 20:58
  • Ok, sorry for the problems, but now I'm getting a bunch of LNK2005 errors that are incomprehensible. This seems to stem from the friend class. I don't think I've defined any duplicates of the operator overload thus far, though. – user3760657 May 02 '15 at 21:36
  • 1
    @user3760657 Show them anyway. – LogicStuff May 02 '15 at 21:38
  • I apologize, nevermind, I was able to fix it by moving the definintion of the friend class into the cpp file rather than in the .h file. My mistake, everything is working now. Thank you very much. – user3760657 May 02 '15 at 21:40
  • @user3760657 I'm glad I could help. – LogicStuff May 02 '15 at 21:41