So I have the following code:
//Get the line
fgets(line, MAX, stdin);
//Remove trailing new line character
line[strcspn(line, "\r\n")] = 0;
//Count number of tokens
int tokenCounter = 1;
for (int i = 0; i < strlen(line); i++){
if (line[i] == ' '){
tokenCounter++;
}
}if (tokenCounter >= 3){
command = strtok(line, " ");
id = strtok(NULL, " ");
name = strtok(NULL, " ");
if (tokenCounter > 3){
for (char *p = strtok(NULL," "); p != NULL; p = strtok(NULL, " ")){
strcat(name, p);
}
}
printf("Command: %s -- ID: %s -- Name: %s\n", command, id, name);
}
What the code is supposed to do is it is supposed to save the first word in the line in the "command" variable, the second word in the line in the "id" variable and the rest of the words in a single variable called "name". But currently its not working properly. It works as described below:
Input > word1 word2 word3
Output > Command: word1 -- ID: word2 -- Name: word3
Input > word1 word2 word3 word4
Output > Illegal Instruction: 4
The correct outputs are supposed to be as follows :
Input > word1 word2 word3
Output > Command: word1 -- ID: word2 -- Name: word3
Input > word1 word2 word3 word4
Output > Command: word1 -- ID: word2 -- Name: word3 word 4
Am I doing something wrong in the loop? if yes, what could be changed?
There's lots that could be wrong with your incomplete code, but one clear problem is the loop:
for (int i = 3; i <= tokenCounter; i++){
name = strtok(NULL, " ");
if (tokenCounter > 3)
strcat(name, strtok(NULL, " "));
}
The first time through the loop, this will assign name
to be pointer to the scanning buffer, which will not work if name
is char name[MAX];
(which it needs to be for any of your code to have any hope of working), so you should be seeing a compile error. Then, strtok
returns NULL
when it gets to the end of the input, which will likely cause an immediate crash when you pass it to strcat
. What you need is something more like
name = strcpy(strtok(NULL, " "));
while (char *tmp = strtok(NULL, " ")) {
strcat(name, " ");
strcat(name, tmp);;
}
Not that this is all that good, as it does not check for buffer overflows, and is just splitting an reassembling tokens, so why bother? Just use strtok(NULL, "\n");
to get the whole rest of the line as a single "token".
If you've erroneously declared char *name;
, that probably explains your crash. When you do
name = strtok(NULL, " ");
if (tokenCounter > 3){
for (char *p = strtok(NULL," "); p != NULL; p = strtok(NULL, " ")){
strcat(name, p);
The first line makes name
point at the strtok buffer, and then in the loop you attempt to append part of the buffer to itself, which causes undefined behavior.