3

I am trying to replicate an exercise from a text book, however the file never reads and so the if statement is triggered telling me that I have not read the file. I have no error message or warnings. I am sure I am missing something fundamental but I just don't know what it could be.... I am running OSX, Clang7.0, using Qt (but I have also tried this in sublime text and it fails there too)

here is the code:

#include <fstream>
#include <iostream>

using namespace std;

int main()
{
    ifstream file_reader ( "myfile.txt" );
    if ( !file_reader.is_open() )
    {
        cout<<"Could not open file!"<<'\n';
    }
    int number;
    file_reader >> number;
    cout<<number;
}

The file is in the same directory as the program files. It is a .txt file simply containing:

12 a b c 

I have tried putting the full path and had a look at some similar threads but it does not seems to be the same problem as this

Thanks for any help in advance

Community
  • 1
  • 1
Harry de winton
  • 969
  • 15
  • 23
  • works fine using gcc version 4.6.4 on ubuntu 12.04, is the txt file in the same directory as the executable? – Jonas Jul 22 '16 at 09:55
  • It works for me on Linux. Please add `<< std::endl` to your output statement and see what happens – GMichael Jul 22 '16 at 09:55
  • Please provide more information. What is the output? Did you tried debugging? Code looks ok, besides lack of return in if body and at the end of main function. – stryku Jul 22 '16 at 09:57
  • So I have found the executable from the sublime version and it works, I guess my question is now: why does it not work inQt? – Harry de winton Jul 22 '16 at 09:58
  • There are not errors, debug turned out nothing, it just fails to find the file. Does Qt create the executables in a different place? I have file in the same folder as the .cpp file but I can't find the executable – Harry de winton Jul 22 '16 at 09:58
  • 3
    Your IDE is probably running your executable with a relative or full path with the current working directory not being what you expect. Try using the full path to your file. – Richard Critten Jul 22 '16 at 09:59
  • so I changed the path to the full one: Documents/Qt/Qt learning/myfile.txt still nothing.... – Harry de winton Jul 22 '16 at 10:01
  • By debugging I mean that you run your pogram step by step and check if everything is ok – stryku Jul 22 '16 at 10:01
  • That's not a absolute path name, it'll be interpreted as relative from your current location. You are missing a / at the beginning. – Dutow Jul 22 '16 at 10:02
  • @Dutow changed to : /Documents/Qt/Qt learning/myfile.txt still nothing, [mentioned this](http://stackoverflow.com/questions/1377078/problem-opening-file-c) – Harry de winton Jul 22 '16 at 10:05
  • 1
    You could add some debug output to report on what the cause of the error is - look at http://stackoverflow.com/questions/17337602/how-to-get-error-message-when-ifstream-open-fails for instance. (So you can distinguish between missing file, invalid path/directory, access permissions, file locked, ...) – AAT Jul 22 '16 at 10:11
  • @stryku I am not entirely sure what I am looking for, file_reader has a lot going on, after the if stream line isostate is 4 and streamsize is 6, could that mean that is is reading but not copying properly? – Harry de winton Jul 22 '16 at 10:12
  • intersting @AAT , added that and i now get "no such file of directory" error but I have added the full path.... – Harry de winton Jul 22 '16 at 10:14
  • So double check the path. fstream on osx is case sensitive so check that too. Create some other file in different directory where you're sure that program'll have the permission to read and try with this new file. And of course debug it step by step. I'm running out of ideas because code looks ok. – stryku Jul 22 '16 at 10:23
  • Does "full path" work if you use it to display the file from command line (with *type* on Win, *cat* on Unixy, for example). – hyde Jul 22 '16 at 10:23
  • I have added the file to the working directory and it all WORKs, can anyone tell me why my full path did not solve this problem though? – Harry de winton Jul 22 '16 at 10:30
  • @hyde I think it is the spaces in the file path, terminal has trouble getting to the directory. any way around this or do I rename the directory? – Harry de winton Jul 22 '16 at 10:33
  • Put quotes around the file name (google bash quoting if you want to learn more, it is a complex subject). – hyde Jul 22 '16 at 10:38
  • SOLVED: seems it was a paths thing, need: /Users/myname at the front of my path....the path was not complete. – Harry de winton Jul 22 '16 at 10:38
  • @hyde quotes within quotes? - "something like "this".??" – Harry de winton Jul 22 '16 at 10:40
  • Good, well done! I think you can use `~` to mean your home directory (so `~/Documents/...`) since OSX is a Unix variant. – AAT Jul 22 '16 at 10:40
  • I meant use quotes on command line, if you have paths with spaces. – hyde Jul 22 '16 at 10:41
  • @hyde I will do my homework on bash quoting, thanks ;) – Harry de winton Jul 22 '16 at 10:48
  • @AAT ~ works in terminal but not in my program....terribly odd?! (I have tried it multiple different ways "~/Doc or ~"/Doc or "/~/Doc etc none of it works. I guess it expects the _full_ path? – Harry de winton Jul 22 '16 at 11:00

1 Answers1

2

As pointed out by others, many IDEs compile your program in some other directory, but they generally also provide a way to copy required files into that same location. Xcode is a case in point. If you find out where your program was created, put myfile.txt in that directory, invoke your program as `./myprogram', and your code will work.

If you want to see what directory your program is running from, you can use getenv("PWD") to look up the working directory, and then do whatever you need to with it.

#include <fstream>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
    cout << "PWD = " << getenv("PWD") << endl; // Inspect working directory

    ifstream file_reader ( "myfile.txt" );
    if ( !file_reader.is_open() )
    {
        cout << "Could not open file!" << endl;
        return -1; // If the file wasn't opened, there's no point in going on
    }
    int number;
    file_reader >> number;
    cout << number << endl;
    return 0; // Always return 0 from main() if successful
}

As you discovered, Documents on OS X lives in your home directory, which would be something like /Users/myusername. Double-quotes are necessary in the shell if your path or file name includes spaces or special characters, but are not necessary from inside your program (i.e. your ifstream() initialization), because the argument will not be interpreted by a shell. The ~ is likewise interpreted by the shell but not by the standard libraries or kernel, which is why using it inside your program doesn't work: ~/ is not a directory name.

Josh Sanford
  • 622
  • 5
  • 18
  • what exactly is getenv("PWD") supposed to output. It really messes with my program. (Otherwise nice answer) – Harry de winton Jul 22 '16 at 14:32
  • `PWD` is the environment variable for the current working directory. If I were to run this code from my `/home/josh` directory, `getenv("PWD")` would return `/home/josh`. When you say that this "messes with my program," are you saying that the program segfaults? If so, then I presume you are running this from inside some IDE which is not passing along the `PWD` environment. What IDE are you using? – Josh Sanford Jul 22 '16 at 15:49
  • If you are interested in seeing what environment variables are being passed to your program, use `int main(int argc, char* argv[], char** env) { while(*env) std::cout << *env++ << std::endl; return 0; }`. – Josh Sanford Jul 23 '16 at 17:48
  • I was running this all from inside Qt so that explains it, thanks for your help – Harry de winton Jul 25 '16 at 11:01