tags:

views:

276

answers:

4

The following code:

char filename[64];
ifstream input;

cout << "Please enter the filename: " << endl;
cin >> filename;

input.open(filename);

if (!input.is_open())
{
    cout << "Opening file " << filename << " failed." << endl;
    exit(1);
}

fails, it enters the if() and exits. What could possibly be the cause for this? I'm using Microsoft Visual C++. When I hardcoded the filename as a constant it instead ended up garbled:

http://pici.se/pictures/CNQEnwhgo.png

Suggestions?

[Edit]

I managed to condense it into this minimal test case that fails:

#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char *argv[]){

    ifstream input;

    input.open("C:\\test.txt");

    if (!input.is_open())
    {
        cout << "Failed." << endl;
        exit(1);
    }

return 0;
}

I was wondering if there might be some disparency with the keymaps? That I'm inputting the filename in some charset while the filesystem knows it under some other name? I'm using Windows, by the way.

[Edit] Thanks for all your help but I give up now. I'll use C style fopen instead. :)

[Edit] Oh my god. Now I feel so stupid. Turns out the file was actually named test.txt.txt and Windows hid the second .txt Once again, thanks for all your help...

A: 

Can you make sure that the filename is what you think it is?

cin >> filename; 
cout << filename; 

ifstream myFile(filename); 
if ( myFile.is_open() ) { 
   // ... 
}

On Unix/Linux systems, remember that file names are case sensitive.

ThisIsMyFile 
thisIsMyFile 

Are two distinct and separate files.

[EDIT]

ifstream::open is defined as:

void open ( const char * filename, ios_base::openmode mode = ios_base::in );

Opens a file whose name is s, associating its content with the stream object to perform input/output operations on it. The operations allowed and some operating details depend on parameter mode.

The function effectively calls rdbuf()->open(filename,mode).

If the object already has a file associated (open), the function fails.

On failure, the failbit flag is set (which can be checked with member fail), and depending on the value set with exceptions an exception may be thrown.


Try changing "C:\test.txt" to simply "test.txt" and run this program from the "C:\" directory.

Here is an exact similar sample:

// ifstream::is_open
#include <iostream>
#include <fstream>
using namespace std;

int main () {

  ifstream infile;
  infile.open ("test.txt");
  if (infile.is_open())
  {
    while (infile.good())
      cout << (char) infile.get();
    infile.close();
  }
  else
  {
    cout << "Error opening file";
  }
  return 0;
}

If something this obvious isn't working, it's time to fire up the debugger.

Chris Kaminski
Also there might be problems with slashes: aren't `/` forward slashes universally accepted. May-be asker is entering double slashes from the keyboard `\\ `?
UncleBens
I'm sure the filename is correct. I'm using Windows. I updated my original post with a smaller code that fails.
jondoe
Still doesn't work with that code. I think I'll just use C style fopen instead, or install a new IDE+compiler.
jondoe
@jondoe: What compiler ARE you using?
Chris Kaminski
@Chris Kaminski, I'm using Microsoft Visual C++ 6.0.
jondoe
@jondoe: what are the results of 'cacls test.txt' and/or 'attrib test.txt'?
Chris Kaminski
A: 

Should that filename read C:\\test.txt or C:\test.txt? The backslash is the escape character in C and C++ and other languages, and you need two backslashes in the input to get one. In other words, you may want C:\\\\test.txt, or C://test.txt is likely to work (forward slashes work like backslashes for a lot of Windows file handling).

EDIT: The backslashes weren't appearing as I intended, as apparently the formatting code here has the same escape convention. I changed this by quoting with backticks, as if the strings were code.

David Thornley
I'm using double slashes. I've tried both forward and backwards.
jondoe
Ugh. I edited to get the backslashes showing up properly.
David Thornley
You don't double forward slashes anywhere but on a URL.
jmucchiello
+2  A: 

I would recommend printing errno from within your failure code (include cerrno.h), or calling perror() (include cstdio.h). Ultimately, the C++ methods are calling C stdlib functions, so even if you aren't getting an exception, you should find the error code.

Anon
perror() claims No such file or directory. Which shouldn't be true.
jondoe
@jondoe - perror() is correct. Now you have to do some more digging to find out why it thinks the file doesn't exist. At least you know that it's not a permissions issue, or one of the dozen other possible reasons for open() to fail. I'd next suggest creating the file for writing, to see where it actually ends up.
Anon
@jondoe - you aren't compiling under Cygwin, are you? Because if you are, you need to use Unix-style pathnames, not Windows-style.
Anon
@Anon, nope. I'm using Microsoft Visual C++ 6.0. I'll just use C style fopen instead.
jondoe
A: 

Does the current user have permission to open the file?

jmucchiello
Yep. I'm administrator.
jondoe
Could some other process have the file locked? An editor? A zombie process?
jmucchiello