Like Tree1Likes
  • 1 Post By oogabooga

Help creating global const char[] to store users home dir

This is a discussion on Help creating global const char[] to store users home dir within the C Programming forums, part of the General Programming Boards category; I am trying to create a global const char array to store the users home directory, well, plus some other ...

  1. #1
    Registered User
    Join Date
    Sep 2012
    Posts
    28

    Help creating global const char[] to store users home dir

    I am trying to create a global const char array to store the users home directory, well, plus some other text, here is an example of what I'm trying to do:

    Code:
    const char configdir[] = strcat(getenv("HOME"), "/.myappconfig");
    int main() {
    // CODE GOES HERE
    }
    Now from doing a web search on my problem I've realized that you can not run functions from outside a function, so how else would I go about doing this? Is what I'm trying to do even possible? I'm fairly new to C, would it just be more practical to just change the working dir to it in the beginning of the main function, and not even make it a variable at all?

    Thanks in advance for helping a noob

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by KoRn KloWn View Post
    Is what I'm trying to do even possible?
    Don't make it const. Give it some storage space. Set it early in main something like this:
    Code:
    char configdir[MAXSIZE];
    
    int main() {
        char *home = getenv("HOME");
        // check that home is not NULL, then
        strcpy(configdir, home);
        strcat(configdir, "/.myappconfig");
        //....
    }
    Adak likes this.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Sep 2012
    Posts
    28
    Thanks, I don't know why I was so obsessed with trying to make it const, I just did it like you showed and it works fine.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Yeah, we've decided we'd like to keep Oogabooga around -- just for laughs you understand!

  5. #5
    Registered User
    Join Date
    Oct 2011
    Posts
    831
    Just to annoy Oogabooga and Adak, here are two helper functions I like to use:
    Code:
    #include <stdlib.h>
    #include <stdarg.h>
    #include <string.h>
    #include <errno.h>
    
    char *strdups(const size_t strings, ...)
    {
    	char       *string, *s;
    	const char *source;
    	size_t      total, len, i;
    	va_list     args;
    
    	/* Find out the total length. */
    	va_start(args, strings);
    	total = 0;
    	for (i = 0; i < strings; i++) {
    		source = va_arg(args, const char *);
    		if (source)
    			total += strlen(source);
    	}
    	va_end(args);
    
    	/* Allocate memory for the new string, plus a '\0'. */
    	string = malloc(total + 1);
    	if (!string) {
    		errno = ENOMEM;
    		return NULL;
    	}
    
    	/* Copy source strings. */
    	va_start(args, strings);
    	s = string;
    	for (i = 0; i < strings; i++) {
    		source = va_arg(args, const char *);
    		if (!source)
    			continue;
    
    		len = strlen(source);
    		if (len < 1)
    			continue;
    
    		memcpy(s, source, len);
    		s += len;
    	}
    	va_end(args);
    
    	/* Terminate the new string. */
    	*s = '\0';
    
    	return string;
    }
    
    char *pathdups(const size_t components, ...)
    {
    	char       *path;
    	const char *part;
    	size_t      total, n, i;
    	va_list     args;
    
    	/* Sum component lengths. */
    	total = components; /* Reserve / for each component. */
    	va_start(args, components);
    	for (i = 0; i < components; i++) {
    		part = va_arg(args, const char *);
    		if (part)
    			total += strlen(part);
    	}
    	va_end(args);
    
    	/* Allocate memory for the resulting path. */
    	path = malloc(total + 2);
    	if (!path) {
    		errno = ENOMEM;
    		return NULL;
    	}
    
    	/* Copy path components. */
    	total = 0;
    	va_start(args, components);
    	for (i = 0; i < components; i++) {
    		part = va_arg(args, const char *);
    		if (!part)
    			continue;
    
    		n = strlen(part);
    		if (n < 1)
    			continue;
    
    		if (total > 0 && path[total - 1] != '/')
    			path[total++] = '/';
    
    		memcpy(path + total, part, n);
    		total += n;
    	}
    	va_end(args);
    
    	/* Terminate the path. */
    	path[total] = '\0';
    
    	/* Combine multiple slashes to one. */
    	i = n = 0;
    	while (i < total) {
    		if (path[i] == '/') {
    			while (path[i] == '/')
    				i++;
    			path[n++] = '/';
    		} else
    			path[n++] = path[i++];
    	}
    	path[n] = '\0';
    
    	return path;
    }
    Both functions use the same interface, with the number of strings first, followed by the strings themselves as separate parameters. (The functions are "variadic"; they can take a variable number of parameters.)

    strdups() returns a dynamically allocated string containing concatenated copies of the source strings.

    pathdups() constructs a path by concatenating directory and file names. Slashes are automatically inserted between parameters, and multiple consecutive slashes combined to a single one. (If you want to make sure you get an absolute path, prepend "/" as the first string.) For example,
    Code:
            char *myappconfig;
    
            myappconfig = pathdups(2, getenv("HOME"), ".myappconfig");
            if (!myappconfig) {
                fprintf(stderr, "Out of memory.\n");
                exit(1);
            }
    If environment variable HOME is undefined or empty, myappconfig will be ".myappconfig". If HOME is say /home/user, then myappconfig will be "/home/user/.myappconfig". It is a very useful function when combining more complex paths, and does not need the programmer to think about where to insert slashes or not.

    While the strcat()+strdup() solution can easily overflow the buffer, strdups() and pathdups() always allocate a long enough buffer dynamically. They are thread-safe, as long as you don't modify those same source strings while another thread is calling strdups() or pathdups() .

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 04-20-2011, 01:19 PM
  2. Replies: 3
    Last Post: 11-15-2009, 03:57 AM
  3. Replies: 7
    Last Post: 04-28-2008, 09:20 AM
  4. Global memory optimizations of const char*
    By Mario F. in forum C++ Programming
    Replies: 14
    Last Post: 08-02-2007, 02:46 PM
  5. const char VS global char
    By COBOL2C++ in forum C++ Programming
    Replies: 2
    Last Post: 09-04-2003, 11:43 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21