views:

170

answers:

6

Basically, I was hoping to sort of keep my files sorted instead of having them all in the same folder as my executable, but referencing files in sub folders relative to my executable has proven difficult.

// DEFINES
#define IMAGE_BACKGROUND "\\content\\images\\background.bmp"
#define FONT_MAIN "\\content\\fonts\\sai.ttf"

The above code obviously does not work. I read supposedly args[0] is somehow my path? Anyone care to elaborate a little more?

int main(int argc, char* args[])
{
A: 

args[0] is the full path name (well, but that is also decided by the OS and shell, so you may get a short file name which is not full) to your "executable file", not its folder. you must truncate it.

try splitpath and joinpath.

Francis
A: 

args[0] is the name used to call your executable, which is not necessarily the full path of your executable. You're interested in the working directory of your executable, which is OS-dependent.

In any case, you have to be careful with relative paths. If your user calls your program from a different directory, your working directory may be something unexpected, and you won't properly reference your files.

Since you're in Windows, you can use the GetModuleFileName function (see the documentation) to get the full name of your executable, like so:

GetModuleFileName(NULL, buffer, length);
Jesse Beder
I'm running windows xp, I would like to be able to get the folder of my executable so I may be able to keep sub folder's relative to my executable.
Ben Adamson
so, is there a better way to do what I am trying to do? I'm using visual c++ express, but I did not think that was relevant.
Ben Adamson
+1  A: 

I should mention that Boost.Filesystem is a nice library that can help you out.

rlbond
While this answer is correct, it's a bit short. The asker is probably interested in the "initial_path" attribute of boost::filesystem. http://www.boost.org/doc/libs/1_39_0/libs/filesystem/doc/reference.html#Attribute-functions which tells you which path the application was started from.Using complete (which uses initial_path), you can then construct any subdir you interested in:boost::filesystem::complete("/content/images/background.bmp");
lefticus
A: 

Have you tryed doing:

#define IMAGE_BACKGROUND "\content\images\background.bmp"

That might be the problem (as i have used images from sub folders like that before)

A: 

This code should work:

#define IMAGE_BACKGROUND "\\content\\images\\background.bmp"

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

    char buf[512];
    int endOfPath = strrchr(args[0], '\\') - args[0];
    strncpy_s(buf, sizeof(buf), args[0], endOfPath);
    strcat(buf, IMAGE_BACKGROUND);

Like the other person said, args[0] is the full path of the executeble, so you can't use that as is. The strrchr function (TWO r's in the middle) finds the last occurrence of a given character and returns a pointer to it. Assuming that you are using one-byte characters, subtracting args[0] from the returned pointer will give you the number of characters between the two pointers -- When you subtract two pointers, your actually subtracting the memory addresses, so what you're left with is an offset, or distance between the pointers. This distance is like the index of the character that was found.

I then use the strncpy_s function to copy endOfPath number of characters from args[0] to our temporary buffer. Now, if your program path was
"C:\Windows\Users\Me\Desktop\myProgram\theProgram.exe"
the buf variable will contain
"C:\Windows\Users\Me\Desktop\myProgram"

I then used the strcat (conCATenation) function to append your constant onto the end.

Note that with your #define, the "\\" is REQUIRED in C/C++, and also note that the " marks will be included where ever you use IMAGE_BACKGROUND.

After those lines of code, buf will contain:
"C:\Windows\Users\Me\Desktop\myProgram\content\images\background.bmp"

Hope that helps and is not too confusing...

JPhi1618
A: 

I actually solved it by using the following code, thank you all for the responses:

// DEFINES
#define IMAGE_BACKGROUND ".\\content\\images\\background.png"
#define IMAGE_BLUEBLOCK ".\\content\\images\\blueblock.png"
#define FONT_MAIN ".\\content\\fonts\\sai.ttf"

Turns out the . gets the "working path directory".

Ben Adamson