Sign in to follow this  
BrknPhoenix

fopen only reading from root directory?

Recommended Posts

BrknPhoenix    122
Alright, strange problem I'm having here... Firstly, I've compiled programs using fopen in Visual C++ Express 2005 before and they work. Just like they should... But right now I'm trying to load a targa image and for some reason, I can only make fopen read from root, and then only if I add a slash before the filename. Here's the code, but there's nothing to it really...
targa_file = fopen("rsoldier.tga", "rb");
Simple as that. I tried running the exe outside the IDE with the file in its directory and it failed. I tried running it from the IDE in the project's directory (which I verified was the directory vc++ ran it from with a GetCurrentDirectory call) and it failed. This is the only thing I can make work...
targa_file = fopen("\\rsoldier.tga", "rb");
Then... it'll read it IF it's on the root of the drive, which obviously does me no good. So uh... what the f**k? So confused...

Share this post


Link to post
Share on other sites
BrknPhoenix    122
Alright, I *think* I solved this but I'm still not entirely sure what the problem was.

I realized that it wasn't just the root it could run from, it was anywhere outside "My Documents", which is where VC2005 stores its projects by default.

So I went to the Properties of My Documents to see if there was some sort of security that prevented accessing the file. There was nothing. I changed nothing. I clicked OK.

Then it worked.

So uh... yeah... not a C++ related problem I guess... but... weird.... *shrug*

So: fun fact! If you recently installed Windows XP and haven't looked at your My Documents properties window yet, fopen won't like you reading from it...

Share this post


Link to post
Share on other sites
haegarr    7372
Presumbly the following stuff is what happens: If you specify a relative path (i.e. one w/o the leading slash) then the libc tries to make the file's path absolute by using the "current working directory" (CWD). I have no clue to what Win32 sets the CWD on start-up since I'm not a windows programmer, but it may e.g. be the user's home directory, or a directory set-up in the IDE's project settings.

From your 2nd post it seems that the user's "Document" directory is what is set at default. What exactly happened could be determined more detailed from the error returned. Read out the variable "errno" if fopen fails, and compare its result with the various possible values. You may have to "#include <errno.h>" for this purpose.

Share this post


Link to post
Share on other sites
Aardvajk    13207
I must admit I've never had this problem. Unless you change the current directory manually or by navigating with a GetOpenFileName dialog or similar, it always seems that the exe directory is the current directory (or, as hydroo correctly points out, the source directory if run from within VS IDE). I'm talking XP as well as 98, 2000 and any other Windows platform I've run my games on.

I suppose the safest way to avoid any issues with this is to use a combination of GetModuleHandle() and GetModuleFileName() to get the absolute path of the exe, then use that as a basis for creating an absolute path to your resource files. I tend to do this in C++ Builder projects a lot since I tend to use Open and Save dialogs more often there.

This would also prevent any problems if your program was run from a different directory at the command line, which will always b*gger up your cwd.

From memory, you do:


HMODULE H=GetModuleHandle(NULL);
char C[256];
GetModuleFileName(H,C,256);


Then bung C in a std::string, use find_last_of to get the final "\\" or "/" and add the name of your file on to that. That should then always work as you would expect regardless of the cwd.

Share this post


Link to post
Share on other sites
Aardvajk    13207
Quote:
Original post by hydroo
if you don´t want to use windowsstuff: afaik the first argument given to your program is the programname+path

argv[0]


I thought that for ages until a conversation here. It is actually not guaranteed to be the full path according to the standard, just the name of the program.

On some platforms you get the full path, on others you don't so you can't rely upon it. That's why I'd suggest (under Windows) the GetModuleFileName() trickery described above. I believe there is no standard and platform-independant way to do this.

Share this post


Link to post
Share on other sites
BrknPhoenix    122
Quote:
Original post by Pipo DeClown
targa_file = fopen("\\rsoldier.tga", "rb");

This is stupid. You probably mean:

targa_file = fopen(".\\rsoldier.tga", "rb");


I don't think you got my point... No I didn't mean that. I was saying the top method was the only thing I could get to work.

And I think everyone is mistaken on what I meant... Normally, when you use fopen you can just specify a filename and it will default to using the directory the application is running from and look for it there.

In this case, for some reason it was failing to open the file. At first I thought it was only reading from c:\, but it in fact turned out that it would not read anything from the "My Documents" folder, where MSVC++2005 stores its projects.

It had nothing to do with what method was used to get the current path, because the fopen shouldn't have needed the path in the first place. It should've defaulted to the current directory. I was under the impression that it wasn't using the correct directory because the fopen was failing, but there was some other reason.

The problem was solved, as I said, by going to the Properties window of My Documents and clicking the OK button. Nothing else. Then fopen would properly read the file.

As I said in my second post... Don't mean to sound rude but yeah, that is what happened :) Thanks for trying to help everyone. The issue has been resolved though.

The only thing that isn't resolved is why would clicking OK on the My Documents Properties window fix the problem. Doesn't really matter though... It's fixed now.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this