Can't read file in build but can read in IDE

As the title says, in Eclipse when I run the code it reads a file with no problems, but as soon as I compile it into an executable, it doesn't work.

The code that reads the file:
1
2
3
4
5
6
7
8
9
10
11
	std::ifstream input(file);

	if (input.is_open()) {
		std::string line;
		while (std::getline(input, line)) {
			std::cout << line << std::flush;
		}
		input.close();
	} else {
		std::cout << "File is missing" << std::flush;
	}


Calling that method:
 
Map map("salsaboy/maps/test.sem", se.getGraphics());
When running, the executable that is running looks in location "salsaboy/maps/test.sem" for the file. This is a relative location rather than an absolute location. It will only work if the executable is in the directory one-above "salsaboy", or if the executable's working directory has been set to the directory one-above "salsaboy".

When you run it in the IDE, an executable is built and run. It will be in some directory. It will have some working directory (which may be the same).
When you build the executable and run it separately, it will be in some directory. It will have some working directory.

Clearly, those directories in bold are not the same in the two cases. You should write your code such that it doesn't rely on the executable being in an exact position relative to the test.sem file, or edit the setting such that the execution from within the IDE and the manual execution use the same directories.
Last edited on
How would you make it not rely on the executable being the position relative to the test.sem file? The file definitely exists.
The file structure is like this:

1
2
3
4
5
6
Lab (the build)
src
salsaboy
|-tiles
|-maps
  |-test.sem


Did I do something wrong there?
Last edited on
How would you make it not rely on the executable being the position relative to the test.sem file?


One way would be to add the path of the executable to the search path and then run the program from the directory that contains the input file.

Another way would be to use command line arguments in your program to be able to tell the program where to look for the input file.

I've tried reading a file in the build of another program, but that doesn't work either. Maybe it's a problem with the system? I'm running this on a Mac if that's important.
I tried replacing reading the file with writing the file, and that also gives me that error. Maybe I'm referring to the file in the wrong way?
Try adding this code to your program and running it. Then we can see where you're starting and if you can get your home directory.

1
2
3
4
5
6
7
8
9
10
11
// add to includes (if not already there)
#include <unistd.h>
#include <stdlib.h>

// first statements in main. what does it print?
char buff[1000];
getcwd(buff, 1000);
cout << "Working directory: " << buff << '\n';
const char *homeDir = getenv("HOME");
cout << "Home directory: " << homeDir << '\n';
return 0; // no sense doing anything more 

It says this:

1
2
Working directory: /Users/[my username]
Home directory: /Users/[my username]


So that's strange. How could I get it to set the home directory to the directory the executable is?
It's actually good that it starts in your home directory. That means if someone else ran it, it would default to their home directory. That gives you a known point to start from. So you could put "salsaboy" in your home directory. Then your original relative path should work.
Last edited on
But can I make it work from another directory? I don't really want to have to put it in their home directory.
Their home directory is the only reasonable place to put it, really. That's what other programs do. Look around in your home directory, especially in the ones starting with a "dot". On linux a lot of stuff is under ".config" and also ".local/share".

However, what you really seem to want is to be able to access the data in the same directory that the program was started from. That's normally done by putting the executable in your path (maybe your personal bin directory under your home directory). That way it can be run from anywhere without having to enter the full absolute path. Then the user would start it from the correct directory.

EDIT: Actually, I'm thinking about data that changes for each user. Data that's the same for all users would be installed in a more central location. On linux, the executable might go under /usr/local/bin/ and the data under /usr/local/share/progname/...
Last edited on
The only to do this that I can see is by getting the whole file path from the executable's directory, cutting out the file, and replacing that with the file path I want.
A simpler solution would be to just have the test file in the same directory as the executable, and have no path in the code; just the filename.

You're running into problems of installation. You're writing a program that relies on the user putting a file in exactly the right place. Make it easy for the user to do it right.
Topic archived. No new replies allowed.