views:

1196

answers:

3

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?

+3  A: 
  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);

Assaf Lavie
thanks for the implicit bool conversion hint and sorry about the excess of information (I felt it was necessary - now I don't, it's fixed). I've yet to test the example with the modifications suggested, I'll get back thereafter.
iCE-9
A: 

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
anon
the file does exist, I've opened it in Windows, by copying the path from the output into Explorer. there are, however some other circumstances that I didn't clarify trying to keep the example simple (not being aware that they might make a difference - again, the code works with XP / Dev-C++ (MinGW-GCC) and even OS X / xcode (GCC)). I'll edit the original question now.
iCE-9
+1  A: 

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.

iCE-9