Creo que ya te habia comentado antes lo de una version reentrante de strtok llamada strtok_r que no modifica el original, y tambien creo que te comenté que seguramente hay algun equivalente en c++ para tokenizar strings sin modificar el original (yo lo ignoro, es cuestion de googlear un poco).
El problema de strtok es que guarda el primer argumento en una global y lo reutiliza cuando vuelves a llamar strtok con el primer argumento nulo. En cambio, la strtok_r solicita un buffer extra que es donde guarda los datos modificados que guardaría en la global en su equivalente no reentrante, y por eso no toca el original.
Creo que te será facil encontrar strtok_r en FreeBSD, y mas sitios con copias e implementaciones. El uso es muy simple: proporcionas un buffer original, un texto de tokenizacion y un buffer para la reentrada (este ultimo asegura que no se modifique el original); el bucle de tokenizacion será igual que con strtok:
Código:
char *pch, *mem;
pch = strtok_r((char*)linia.c_str(), " ", &mem);
while(pch) {
pch = strtok_r(0, " ", &mem);
}
//aqui sigues teniendo la variable 'linea' intacta
Ten en cuenta que la funcion strtok_r no forma parte del estandar de C (y por supuesto tampoco de c++), por lo que algunas implementaciones que puedas encontrar estaran sometidas a licencias y cosas de esas que nadie se mira pero que si estan ahi de algo deben servir, no se.
Si no te convence lo del strtok_r, puedes ir a lo facil y duplicar la linea para trabajar con el duplicado, de esa forma te será igual si se modifica o no (que es lo que intentabas hacer con linia.copy).
De todas formas, ya que estas trabajando en c++ tal vez deberías buscar la forma de hacerlo con strings en vez de usar las funciones de C; para la version de strtok en c++ lo siento pero no puedo ayudarte, tal vez alguien mas pueda echarte un cable
vosk