Как добавить токены в строковую переменную в C? - PullRequest
1 голос
/ 11 ноября 2019

Итак, у меня есть следующий код:

//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);
}

Код должен делать то, что он должен сохранить первое слово в строке в переменной «command», а второе слово встрока в переменной «id», а остальные слова в одной переменной с именем «name». Но в настоящее время его не работает должным образом. Он работает, как описано ниже:

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

Я что-то не так делаю в цикле? если да, что можно изменить?

1 Ответ

0 голосов
/ 11 ноября 2019

Есть много вещей, которые могут быть не правы в вашем неполном коде, но одной очевидной проблемой является цикл:

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, а затем в цикле вы пытаетесь добавить часть буфера к себе, что вызывает неопределенное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...