James Le
James Le

Reputation: 51

How do I open a file in c that is in the same directory as the program?

Hi everyone I am trying to open a file from a server program that I wrote for my network programming class to send to my client program. I have tried using fopen,

  strcat(cwd, msg);              //i append the directory to the filename
  printf("%s\n", cwd);

  if(n>0){
     req = fopen(msg, "r");      //fopen(~\\blah\\blah\\blah\\msg)

msg is the name of a txt file.

I want this done in c.

Any ideas? greatly appreciated.

would like to add that req turns out to be null even though the directory printed out is correct.

Upvotes: 3

Views: 2946

Answers (2)

Joseph Quinsey
Joseph Quinsey

Reputation: 9972

From your comment in the code:

// fopen(~\\blah\\blah\\blah\\msg)

the variable cwd may be ~. If so, then as FatalError mentions, fopen() won't expand it for you. Only the shell does this, on systems I've used.

The work-around is e.g. to call getenv("HOME"), and then expand the ~ yourself.

Upvotes: 0

Dolda2000
Dolda2000

Reputation: 25865

The real answer to your question is that you can't. C provides no way for you to know where the file your program image was constructed from resides, partly because it makes no assumptions that it was even constructed from a file. So there's no generic, portable way that is guaranteed to work.

However, in certain environments and under certain conditions, you can use argv[0], which might contain the path using which the program file was found. This is frequently the case under Unix/Linux (but not necessarily -- you are beholden to the program that started your program). I have no clue how it is on other systems like Windows.

If you want to use that method, you can do something like this:

FILE *openrelative(char *base, char *name)
{
    char *buf1, *dir, *buf2;
    int len;
    FILE *ret;

    buf1 = strdup(base); /* dirname might modify its argument, so copy base. */
    dir = dirname(buf1);
    len = strlen(dir) + 1 + strlen(name) + 1;
    buf2 = malloc(len);
    snprintf(buf2, len, "%s/%s", dir, name);
    ret = fopen(buf2, "r");
    free(buf2); free(buf1);
    return(ret);
}

Then, call this function from main as openrelative(argv[0], "msg.txt"). Or from somewhere else, but you need to make argv[0] available somehow.

Since these methods aren't guaranteed to work, however, you shouldn't really use them. Especially not if your program is supposed to be portable or used by others.

Upvotes: 2

Related Questions