K. Ori
K. Ori

Reputation: 43

Assign a string field of a struct in C

I try to write a program using this structure containing strings :

typedef struct s_conf
{
    char *shell1;
    char *shell2;
    char *shell3;
    char *shell4;
    char *server_ip;    
} t_conf;

Parsing a config text file line per line, I get this information and I store it into variables such as line1 and line4. Now I want to assign my struct fields the values of the variables line1 and line4:

char *line1 = "/var/www/host/current/app/console robot:file";
char *line4 = "192.168.00.00";

t_conf *conf;
if ((conf = malloc(sizeof(t_conf))) == NULL)
        {
            fprintf(stderr, "Malloc error\n");
            return (-1);
        }

strcpy(conf->shell1, line1);
strcpy(conf->server_ip, line4);

printf("line1 : '%s'\n"; line1);
printf("line4 : '%s'\n"; line4);

printf("t_conf->shell1 : '%s'\n", conf->shell1);
printf("t_conf->server_ip : '%s'\n", conf->server_ip);

The output :

line1 : '/var/www/host/current/app/console robot:file'
line4 : '192.168.00.00'
t_conf->shell1 : '/var/www/host/current/app'
t_conf->server_ip : '192.168.00.00'

How to correctly assign the c string t_conf->shell1 ? I try other functions like memcpy(), strdup() and allocate the variable with malloc : t_conf->shell1 = malloc(strlen(line1) + 1) but it gives me the same result, I lose a portion of line1 ?

Upvotes: 0

Views: 1294

Answers (2)

David Ranieri
David Ranieri

Reputation: 41045

strcpy(conf->shell1, line1);

You need space to store line1

Furthermore (as pointed out by @cat in comments) strcpy is dangerous and must be avoided in production code, an alternative is strdup (non standard), or snprintf:

size_t size = strlen(line1) + 1;
conf->shell1 = malloc(size);
snprintf(conf->shell1, size, "%s", line1);

The space should be returned with free(conf->shell1); when it is no longer needed.

Same for conf->server_ip

Note that if you don't need to modify those strings, you don't need to copy, just assign:

conf->shell1 = line1;

Upvotes: 1

chux
chux

Reputation: 154312

I try to write a program using this structure containing strings :

struct s_conf below contains 5 pointers. It does not contains any strings. With the C standard library, a string is an array of characters up to and including a final null character ('\0'). For your code to work, memory for these arrays are needed - someplace.

typedef struct s_conf {
    char *shell1;
    char *shell2;
    char *shell3;
    char *shell4;
    char *server_ip;    
} t_conf;

strcpy(conf->shell1, line1); fails because conf->shell1 does not yet have a value pointing to available memory for the copy.


Populate these 5 pointers with values pointing to memory containing the needed data.

// allocate memory for the structure
conf = malloc(sizeof *conf);
assert(conf);

// Simply copy the pointer if `line1` will exist for as long as `conf`.
conf->shell1 = line1;

// or
// Create an allocated copy.
conf->shell1 = strdup(line1);
// With this method, be sure to free the memory before freeing conf
...
free(conf->shell1);
free(conf);

strdup() is not a standard library function, yet very common. Make an equivalent if needed. Example: (tailor to your needs)

char *my_strdup(const char *s) {
  if (s) {
    size_t sz = strlen(s) + 1;
    char *dest = malloc(sz);
    if (dest) {
      return memcpy(dest, src, sz);
    }
  }
  return NULL;
}

Upvotes: 1

Related Questions