cgccenvironment-variables

checking environment variables in C


I am new to C (somewhat seasoned in Perl, from a long ago, and Lua more recently), and just can't figure out what goes wrong in trying to patch an old program written in C: I'd like it to set an environment variable to a default value in case it is undefined, but I keep getting the first output consistently. My code goes as follows:

#include <stdio.h>

int main()
{
    const char* mappath = "XDG_DATA_HOME";
    char* mapdir = getenv(mappath);
    if (mapdir = "") {
        printf("set XDG_DATA_HOME environment variable");
    }
    else {
        printf("%s");
    }
}

I get the first message regardless of whether I define de environment or not. Of course I shall replace the simple report message with other code in my program, but first I need to figure out how to test for the existence of the definition of the environment variable.

How do I fix it so that I may get the value of HOME if set, and the message otherwise?


Solution

  • There are several issues in your code:

    1. if (mapdir = ""):
      = is performing an assignment, not comparison (which is what == is used for usually). And in any case comparison for strings should be done with functions like strcmp and not with the comparison oprator (==).
    2. According to the documentation getenv returns NULL if there is no match (and not an empty string).
    3. When you attempt to print the value with printf("%s"); you omitted the value to print.

    A fixed version:

    #include <stdio.h>
    #include <stdlib.h> // for `getenv`
    
    int main()
    {
        const char* mappath = "XDG_DATA_HOME";
        char* mapdir = getenv(mappath);
        if (mapdir == NULL) {  // can also be written as `if (!mapdir) {`
            printf("set XDG_DATA_HOME environment variable");
        }
        else {
            printf("%s", mapdir);
        }
    }
    

    Note:
    As mentioned above getenv will return NULL if the value is unset.
    However there can be also a situtation where the value is set but to an empty string (in this case an empty string will be returned).
    If you want to distinguish between these 2 cases you can do it in the following way:

    #include <stdio.h>
    #include <stdlib.h> // for `getenv`
    
    int main()
    {
        const char* mappath = "XDG_DATA_HOME";
        char* mapdir = getenv(mappath);
        if (mapdir == NULL) {  // can also be written as `if (!mapdir) {`
            printf("not set");
        }
        else {
            if (strcmp(mapdir, "") == 0) {
                printf("set to an empty string");
            }
            else {
                printf("set to: %s", mapdir);
            }
        }
    }
    

    Note the usage of strcmp as mentioned above to compare strings.