0

I'm quite confused about this weird behaviour of my .cpp project. I've got the following folder structure:

include/mylib.h
myproject/src/eval.cpp
myproject/data/file.csv
myproject/Makefile

In eval.cpp I include mylib.h as follows:

#include "../../include/mylib.h"

and compile it through Makefile:

all:
     g++ -I include ../include/mylib.h src/eval.cpp -o eval.out

Now in my eval.cpp I'm reading the file.csv from data directory and if I refer to it like this

../data/file.csv

it doesn't find it (gets empty lines all the time), but this

data/file.csv

works fine.

So, to include mylib.h it goes two directories up (from src folder) which seems right. But it doesn't make sense to me that to refer to another file from the same piece of code it assumes we are in project directory. I suppose it is connected with Makefile somehow, but I'm not sure.

Why is it so?

EDIT: After a few thing I tried it seems that the path which is used is not the path from binary location to the data location, but depends on where from I run the binary as well. I.e., if I have binary in bin directory and run it like:

./bin/eval.out

It works with data/file.csv.

This:

cd bin
./eval.out

works with ../data/file.csv.

Now it seems very confusing to me as depending on where I run the program from it will give different output. Can anyone please elaborate on the reasons for this behaviour and if it is normal or I'm making some mistake?

sashkello
  • 17,306
  • 24
  • 81
  • 109

1 Answers1

2

It is so because (as explained here ) the compiler will search for #included files with quotes (not with brackets) with the current working directory being the location of the source file.

Then, when you try to open your .csv file, it's now your program that looks for a file. But your program runs with the current working directory being myproject/ which explains why you must specify data/file.csv as your file path, and not ../data/file.csv. Your program does not run in your src folder, it will run in the directory the binary ends up being invoked from.

You could have noticed that in your Makefile, your -I options specify a different path for your header file than your .cpp file.

EDIT Answer: It's quite simple actually and completely normal. When you invoke your binary, the directory which you're in is the current working directory. That is, if you run it with the command ./myproject/bin/eval.out, the current working directory is . (e.g. /home/the_user/cpp_projects). My post was a bit misleading about that, I corrected it.

Note: You can use the command pwd in a command prompt to know which is the current working directory of this prompt (pwd stands for "print working directory").

Community
  • 1
  • 1
JBL
  • 12,588
  • 4
  • 53
  • 84
  • Yep, the .h file location does make sense in both cases. So, if I put Makefile in src directory the path should be changed to ../data/file.csv? – sashkello May 17 '13 at 10:58
  • What matters is where the outputted binary ends up. If it is in the src directory, then yes. Usually though, it's more common to see the binary being sent into a `/bin` directory or directly at the project's root directory. It makes the hierarchy cleaner (i.e. `src` contains source files and nothing else), and in the case of the project's root directory, can make filepaths easier to determine/more intuitive (not having to jump back a few steps, then go down again in the hierarchy). – JBL May 17 '13 at 11:10
  • OK, so if I do -o bin/eval.out, then I should change path to ../data/file.csv, is that right? – sashkello May 17 '13 at 11:17
  • Exactly. The path must be relative to the binary location. Please note that it works while you don't [change the current working directory](http://stackoverflow.com/questions/3485166/change-current-working-directory-c), which is, initially, the directory where the binary is located. – JBL May 17 '13 at 11:23
  • I've played with it a bit more and it seems that it's more weird than this. I'm editing my question to add some info. – sashkello May 19 '13 at 23:29
  • So, what would I do if I want a program to run in the same way from any directory I launch it? Change the working directory within c++ code? – sashkello May 19 '13 at 23:47
  • You can use [`chdir`](http://linux.die.net/man/2/chdir) to make sure the same directory is used as current working directory, no matter what was the cwd when your binary was invoked. – JBL May 19 '13 at 23:51