Your code will crash on this line:
strcat(data,strtok_r(NULL," ",&save));
Because you never reserved space for data
. strcat
will try to write to a NULL
memory address.
Another thing to note is that you shouldn't rely on save
to check for the end of the line. According to strtok
's manpage:
The saveptr argument is a pointer to a char * variable that is used internally by strtok_r() in order to maintain context between successive calls that parse the same string.
Relying on the value of saveptr
outside of strtok_r
breaks the abstraction layer, you shouldn't assume anything about how strtok
uses saveptr
. It's bad practice.
A slightly better approach is to keep a pointer to the previous token returned by strtok
, and a pointer to the current token. When strtok
returns NULL, meaning there are no more tokens, then prev
will point to the last token, which is your key
. Here's some code:
char *key = NULL, *save=NULL;
char *prev, *curr;
char comando[1024];
char data[1024];
data[0] = '\0';
fgets(comando, 512, stdin);
prev = curr = strtok_r(comando, " ",&save);
while (curr != NULL) {
prev = curr;
curr = strtok_r(NULL, " ", &save);
if (curr != NULL)
strcat(data, prev);
}
key = prev;
Note that I allocated space for data
by declaring it as array instead of pointer. The instruction
data[0] = '\0';
is there to make sure that strcat
finds the null terminating byte in the first call.
You can replace the use of prev
directly by key
, I left it that way to make the code more readable.
A word of advice: always remember that strtok
modifies its argument destructively (you lose the identity of the delimiting bytes), and that you can't call it with constant strings.
Note: data
will contain every word concatenated. You lose the spaces. I'm not sure if this is what you want. If it's not, you might want to use something better than strcat
(which is not very efficient, btw). For example, you code use sprintf
to print the token into data
with a leading space, and keep a pointer to the next free position in data
.