Question

I know there's been a handful of questions regarding std::ifstream::open(), but the answers didn't solve my problem. Most of them were specific to Win32, and I'm using SDL, not touching any OS-specific functionality (...that's not wrapped up into SDL).

The problem is: std::ifstream::open() doesn't seem to work anymore since I've switched from Dev-C++ to Code::Blocks (I've been using the same MinGW-GCC back-end with both), and from Windows XP to Vista. (It also works perfectly with OS X / xcode (GCC back-end).)

My project links against a static library which #includes <string>, <iostream>, <fstream> and <cassert>, then a call is made to functionality defined in the static library, which in turn calls std::ifstream::open() (this time, directly). Following this, the stream evaluates to false (with both the implicit bool conversion operator and the good() method).

Code:

#include "myStaticLibrary.hpp"

int main(int argc, char **argv)
{
  std::string filename("D:/My projects/Test/test.cfg");

  std::cout << "opening '" << filename << "'..." << std::endl;
  bool success(false);

  // call to functionality in the static library
  {
    std::ifstream infile(filename.c_str());
    success = infile.good();
    // ...
  }
  // success == false;

  // ...
  return 0;
}

stdcout.txt says:

opening 'D:/My projects/Test/test.cfg'...

When I open stdcout.txt, and copy-paste the path with the filename into Start menu / Run, the file is opened as should be (I'm not entirely sure how much of diagnostic value this is though; also, the address is converted to the following format: file:///D:/My%20projects/test/test.cfg).

I've also tried substituting '/'s with the double backslash escape sequence (again, slashes worked fine before), but the result was the same.

It is a debug version, but I'm using the whole, absolute path taken from main()'s argv[0].

Where am I going wrong and what do I need to do to fix it?

Was it helpful?

Solution

I have overseen the importance of the fact that the function in question has close()d the stream without checking if it is_open().

The fact that it will set the stream's fail_bit (causing it to evaluate to false) was entirely new to me (it's not that it's an excuse), and I still don't understand why did this code work before.

Anyway, the c++ reference is quite clear on it; the problem is now solved.

OTHER TIPS

  1. Please create a minimal set that recreates the problem. For example, in your code above there's parsing of argv and string concatentation, which do not seem like a necessary part of the question. A minimal set would help you (and us) see exactly what's going wrong, and not be distracted by questions like "what's GetPath()?".
  2. Try to do this instead of assert(infile.good()):

    assert(infile);

The following code:

#include <string>
#include <iostream>
#include <fstream>
#include <assert.h>
using namespace std;;

int main(int argc, char **argv)
{
  std::string filename("D:/My projects/Test/test.cfg");
  std::cout << "opening '" << filename << "'..." << std::endl;
  std::ifstream infile(filename.c_str());
  assert(infile.good()); // fails

  return 0;
}

works fine on my Windows system using MinGW g++ 4.4.0, if I create the required directory structure. Does the file test.cfg actually exist? If you are opening a stream for input, it wioll fail if the file is not there.

Edit: To remove any DevC++ to CB issues:

  • build using command line only
  • make sure you rebuild the static library too
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top