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