0

I've got this code that uses an fstream to read and write to a file. The fstream object is held as a member of an object, and is initialized in the constructor like so:

idmap.open(path, std::fstream::in | std::fstream::out | std::fstream::app);

The file gets properly created if it doesn't already exists. Then it gets written to like so:

idmap.seekp(0, std::fstream::end);
idmap << str.size() << ':' << str << '\n';
idmap.flush();
idmap.sync();

It's supposed to be read like this but I don't know if it works because the file has always been empty:

idmap.seekg(0);
while (!idmap.eof()) {
    idmap.getline(line, 1024);

    idtype id = getIDMapEntry(std::string(line));
    if (identifier.compare(nfile.getIdentifier()) == 0) {
        return nfile;
    }
}

Then it's closed when the program exits:

idmap.close();

It's probably something else in the program but I figure I'll ask here in case I did something stupid, and dig through everything else in parallel.

meustrus
  • 6,637
  • 5
  • 42
  • 53
  • 1
    It should be easy enough for you to create a small stand alone program that tests just what you've posted here. That will help pinpoint where your problem is. – Trent Aug 17 '12 at 19:04
  • Did you try flushing the stream? – celtschk Aug 17 '12 at 19:10
  • Yes, just forgot to include that in the example code. – meustrus Aug 17 '12 at 19:19
  • 1
    Aside: I don't recommend using `.eof()` as a loop condition. It [almost always produces buggy code](http://stackoverflow.com/questions/21647/reading-from-text-file-until-eof-repeats-last-line) (as it has in this case). Instead, prefer `while(idmap.getline(line, 1024)) { ... }`. Or, even better, using `std::getline`, thus: `std::string line; while(std::getline(idmap, line)) { ... }`. – Robᵩ Aug 17 '12 at 20:36
  • What makes you believe that the file is empty? Is it that compare function does or doesn't trip? If so, you are suffering from the `.eof()` bug. In your case, it causes an extra blank line to appear in your input. That blank line presumably fails your `getIDMapEntry()`. – Robᵩ Aug 17 '12 at 20:47
  • I know it's empty because when I look at it in the filesystem it says "zero bytes" and `cat file.txt` prints nothing. – meustrus Aug 17 '12 at 21:02

1 Answers1

1

Works for me.

This program, except for the .eof() bug, works precisely as expected:

#include <fstream>
#include <iostream>

int main() {
  std::fstream idmap;
  const char path[] = "/tmp/foo.txt";
  idmap.open(path, std::fstream::in | std::fstream::out | std::fstream::app);

  std::string str("She's no fun, she fell right over.");
  idmap.seekp(0, std::fstream::end);
  idmap << str.size() << ':' << str << '\n';
  idmap.flush();
  idmap.sync();

  idmap.seekg(0);
#if 1
  // As the user presented, with .eof() bug
  char line[1024];
  while (!idmap.eof())
  {
    idmap.getline(line, 1024);

    std::cout << line << "\n";
  }
#else
  // With fix for presumably unrelated .eof() bug
  std::string line;
  while(std::getline(idmap, line)) {
    std::cout << line << "\n";
  }
#endif

}
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • Thanks for the thorough description. I'll mark this as the answer although it doesn't solve my problem, since it does prove my question wasn't thorough enough. Although there really isn't anything else in the entire application that I think could interfere with file handling, and a separate file did write correctly using ofstream in the same directory. – meustrus Aug 17 '12 at 21:01