2012-02-23 3 views
12

Итак, я понимаю, что strtok изменяет свой входной аргумент, но в этом случае он сворачивает входную строку только в первый токен. Почему это происходит, и что я могу сделать, чтобы исправить это? (Обратите внимание, я не говорю о «температуре» переменной, которая должна быть первой лексемой, а переменный «вход», который после одного вызова strtok становится «это»)Почему strtok меняет свой вход так?

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 

int main(int argc, char* argv[]) { 
    char input[]="this is a test of the tokenizor seven"; 
    char * temp; 
    temp=strtok(input," "); 
    printf("input: %s\n", input); //input is now just "this" 
} 

ответ

24

Когда strtok() находит токен, он меняет символ сразу после токена в \0, а затем возвращает указатель на токен. В следующий раз, когда вы вызываете его с аргументом NULL, он начинает искать разделители, которые завершили первый токен, т. Е. После \0 и, возможно, дальше.

Теперь, оригинальный указатель на начало строки по-прежнему указывает на начало строки, но первый маркер теперь \0 -завершённый - т.е. printf() считает, что конец маркера конец строки , Остальная часть данных все еще существует, но \0 останавливает printf(). Если вы использовали for -loop, чтобы пройти исходную строку ввода до исходного количества символов, вы обнаружите, что данные все еще там.

+1

О, я вижу. Мое понимание того, как работает strtok, было пустым - я предположил, что он оттолкнул токен, а затем сдвинул указатель на первый символ после делиметра. Во всяком случае, спасибо! Это был очень ясный и полезный ответ. – user1209326

+0

Это было поучительно, спасибо. –

2

Это потому, что strtok вставляет нули в каждый разделитель, поэтому вы используете повторные вызовы strtok для получения каждого токена. Строка ввода не может быть использована, как только вы начнете использовать strtok. Вы не «исправляете» его - так оно и работает.

+0

Спасибо за такой быстрый ответ. Конечно, когда я сказал «исправить это», я имел в виду «как получить результат, который я хочу», но я благодарю вас за то, что вы нашли время, чтобы помочь мне. – user1209326

+0

Если вам нужна незатронутая копия входной строки, вам нужно сделать ее копию перед strtok. – Joe

3

Вы должны распечатать маркер, который вы получаете от strtok, и не беспокоиться о входном массиве, потому что NULL будут вставлены strtok. Вам нужны повторные вызовы для получения всех токенов:

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 

int main(int argc, char* argv[]) { 
    char input[]="this is a test of the tokenizor seven"; 
    char * temp; 
    temp=strtok(input," "); 
    while(temp != NULL) { 
    printf("temp is \"%s\"\n", temp); 
    temp = strtok(NULL, " "); 
    } 
} 
+0

Как я уже говорил выше, ясно, что у меня была неправильная идея о том, как strtok фактически символизировал вещи. Спасибо за вашу помощь! – user1209326