所以我有以下代码:
//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);
}
代码应该做的是,应该将行中的第一个单词保存在“命令”变量中,将行中的第二个单词保存在“ id”变量中,其余的单词保存在单个变量中称为“名称”。但目前其无法正常工作。它的工作原理如下:
Input > word1 word2 word3
Output > Command: word1 -- ID: word2 -- Name: word3
Input > word1 word2 word3 word4
Output > Illegal Instruction: 4
正确的输出应该如下:
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
我在循环中做错什么了吗?如果是,可以更改什么?
您的代码不完整可能有很多错误,但是一个明显的问题是循环:
for (int i = 3; i <= tokenCounter; i++){
name = strtok(NULL, " ");
if (tokenCounter > 3)
strcat(name, strtok(NULL, " "));
}
第一次循环时,这会将name
分配为指向扫描缓冲区的指针,如果name
为char name[MAX];
,则该指针将不起作用(需要让您的任何代码有希望)工作),因此您应该会看到编译错误。然后,strtok
到达输入的末尾时将返回NULL
,当您将其传递给strcat
时可能会导致立即崩溃。您需要的是更多类似的东西
name = strcpy(strtok(NULL, " "));
while (char *tmp = strtok(NULL, " ")) {
strcat(name, " ");
strcat(name, tmp);;
}
并不是说就这么好,因为它不检查缓冲区溢出,而只是拆分一个重新组装的标记,所以为什么要打扰?只需使用strtok(NULL, "\n");
将整个行的其余部分作为一个单独的“令牌”即可。
如果您错误地声明了char *name;
,则可能是导致崩溃的原因。当你做
name = strtok(NULL, " ");
if (tokenCounter > 3){
for (char *p = strtok(NULL," "); p != NULL; p = strtok(NULL, " ")){
strcat(name, p);
第一行使name
指向strtok缓冲区,然后在循环中尝试将缓冲区的一部分附加到自身,这将导致未定义的行为。