0

I've got a class:

class DataBase{
private:
    fstream db_file;
public:
    DataBase(){
        db_file.open("db.txt", std::ios::in | std::ios::out);
    }

    void couteverything(){
        string line;
        if(db_file.good() && db_file.is_open()){
            getline(db_file, line);
            cout << line;
            cout << "ok";
        }

    }

    ~DataBase(){
        db_file.close();
    }
};

and a file db.txt with some content. I'd like to cout it to the console, but it's not working - as if the file was empty (nothing appears on the screen).

tomdavies
  • 1,896
  • 5
  • 22
  • 32
  • 1
    Does you'r file start with a newline character? – Hariprasad Dec 17 '13 at 13:21
  • When you say nothing appears on the screen, does that include the "ok"? If so, then either `db_file.good()` returned false, or `db_file.open()` returned false, or you didn't call `couteverything()`. – odyss-jii Dec 17 '13 at 13:21
  • Try an `else { cout << "not ok"; }` too while you are there – doctorlove Dec 17 '13 at 13:21
  • Put a std::clog << "Destruct" << std::endl in your destructor (or set a break point) –  Dec 17 '13 at 13:29
  • Is the file in the current directory? – doctorlove Dec 17 '13 at 13:32
  • Given that you never test the status of your input operations (`open`, `getline`), it's impossible to say where things go wrong. – James Kanze Dec 17 '13 at 13:48
  • It seems like `if(db_file.good() && db_file.is_open()){ getline(db_file, line);` ought to be `while (getline(db_file, line)) {` if you want to read and display the whole file. – Joe Z Dec 17 '13 at 14:03

1 Answers1

1

In your constructor, you do not test whether the file opened successfully. Therefore, you have no idea if the file opened successfully. Thus, your couteverything method can't distinguish EOF from "failed to open." You might consider adding a check:

DataBase(){
    db_file.open("db.txt", std::ios::in | std::ios::out);

    if (!db_file.is_open() || !db_file.good()) {
        // put an error message here, or throw an exception.  Up to you.
    }
}

Once you're in couteverything(), presumably you want to loop over the entire file. You need a loop for that, not an if statement. Something like this:

    while (getline(db_file, line)) { 
        cout << line;
        cout << "ok";
    }

Even if you did not want to loop here (in which case coutnextline() might be a better name for the method), you still want to test the result of getline() directly, rather than testing good() and is_open() before each read. You need to test whether getline() succeeds, otherwise your code will try to process one line beyond EOF or a read error.

    if (getline(db_file, line)) { 
        cout << line;
        cout << "ok";
    } 

If you do only want to output a line at a time, I'm not sure how the code that calls this would know when to stop. But, that's a different problem. (Hint: You could solve that by returning a bool from this line-at-a-time method.)

Joe Z
  • 17,413
  • 3
  • 28
  • 39