Reputation: 21
typedef struct node{
char *name;
//etc...
}N
If i had char *string got from stdin and i wanted to pass it to N, i could do easily N->name=string, or it would be bettere to use strcpy? which is more correct? which is more efficient? why?
Upvotes: 0
Views: 216
Reputation: 388
You want to use a buffer to read your input from stdin. But if you don't make a copy, your string will be lost at the next read iteration. If you are going to allocate memory, and if you don't know the size of the string you receive, you should use a function like strdup instead of strcpy.
node->name = strdup(string_to_copy);
if (node->name == NULL)
printf("My allocation has failed!\n");
The allocated memory will have to be freed afterward. If the allocation fails, you will have a message (you should always check the success of your memory allocation).
If you don't want to allocate memory and if you know that the size of your input will never be higher than say, 100, you could get away with something like this:
typedef struct node{
char name[100];
//etc...
}N
In that case you could use the following. Note that strcpy is a dangerous function that should be used with extra-care:
strncpy(node->name, buffer, 100);
strcpy(node->name, buffer);
EDIT:
Here is a way to free your memory properly:
if (node->name != NULL)
{
free(node->name);
node->name = NULL;
}
This construction will free your memory and helps preventing double-free.
Upvotes: 2
Reputation: 43327
Answering "the result is the same, but what's the difference?" (from comment)
Starting from:
N *node = malloc(sizeof(N));
char input_from_stdin[80];
If we do
strcpy(node->name, input_from_stdin);
we invoke undefined behavior, but it might appear to work.
If we do
node->name = input_from_stdin;
than node->name
only contains its expected value until input_from_stdin
is reused, which is typically when the next line is read form input.
If we do
node->name = malloc(strlen(input_from_stdin) + 1);
strcpy(node->name, input_from_stdin);
we make a copy of the input that lives until we free it; but we must remember to free node->name
before freeing node
.
We can also do
typedef struct node{
char name[MAXSIZE];
//etc...
}N;
and then expect
strncpy(node->name, input_from_stdin, MAXSIZE-1)[MAXSIZE-1] = 0;
to work.
Some poeple do
strncpy(node->name, input_from_stdin, MAXSIZE);
which is valid but getting it back out again is touchier. This is rarely seen out of fixed-width records on disk now. We don't like MAXSIZE
much anymore and prefer everything stretchy.
Upvotes: 0