c ++ strtok в функции изменяет исходное строковое значение в качестве параметра - PullRequest
0 голосов
/ 01 октября 2011

Когда я использую strtok для токенизации строки c ++, возникает непонятная проблема, см. Простой код ниже:

void a(string s){
    strtok((char*)s.c_str(), " ");
}
int main(){
    string s;
    s = "world hello";
    a(s);
    cout<<s<<endl;
    return 0;
}

программа выводит "world".Разве он не должен выводить «привет»?Поскольку я передаю строку в качестве параметра-значения для функции a, strtok не должен изменять исходный s ... Может кто-нибудь объяснить этот трюк.спасибо.

Ответы [ 3 ]

0 голосов
/ 01 октября 2011

c_str() возвращает указатель const, который обещает компилятору, что указанная вещь не будет изменена. И тогда вы вызываете strtok, который его модифицирует.

Когда вы лжете компилятору, вы будете наказаны.

0 голосов
/ 01 октября 2011

Так работает strtok (). Он использует первый параметр в качестве буфера. Приведя его к типу char *, вы позволяете ему изменять строку. strtok () не знает об исходной std :: string. Он также хранит указатель строки в статической переменной, поэтому в следующий раз вы должны вызывать его с нулевым указателем, чтобы продолжить анализ той же строки.

Кстати, в c ++ вместо этого вы должны использовать std :: istringstream. Он не использует внутреннюю статическую переменную, которая не является поточно-ориентированной. И вы можете извлечь параметры непосредственно в int, double и т. Д., Как мы делаем с cin. std :: ostringstring заменяет sprintf ().

0 голосов
/ 01 октября 2011

Проблема в (char*)s.c_str(), вы отбрасываете константность и изменяете содержимое string так, как вы не должны.Хотя исходный s не должен быть изменен, я полагаю, что вы, возможно, попали под умную оптимизацию, которая ожидает от вас игры по правилам.Например, реализация COW string могла бы показать такое поведение.

...