如何将标记附加到C中的字符串变量?

问题描述 投票:1回答:1

所以我有以下代码:

//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

我在循环中做错什么了吗?如果是,可以更改什么?

c string append token
1个回答
0
投票

您的代码不完整可能有很多错误,但是一个明显的问题是循环:

for (int i = 3; i <= tokenCounter; i++){
    name = strtok(NULL, " ");
    if (tokenCounter > 3)
        strcat(name, strtok(NULL, " "));
}

第一次循环时,这会将name分配为指向扫描缓冲区的指针,如果namechar 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缓冲区,然后在循环中尝试将缓冲区的一部分附加到自身,这将导致未定义的行为。

© www.soinside.com 2019 - 2024. All rights reserved.