2010-04-10 15 views
6

OK. Por ejemplo, tengo esta línea en mi archivo txt:División doble en C

1|1,12;7,19;6,4;8,19;2,2
Como se puede ver, tiene 2 partes, separadas por |. No tengo problemas para obtener ambas partes y separar la segunda parte 1,12;7,19;6,4;8,19;2,2 con el separador ;. PERO tengo problemas para separarme más por , para obtener el primer y segundo número de cada conjunto.

Este es mi código actual:

result = strtok(result, ";"); 

    while(result != NULL) { 
     printf("%s\n", result); 
     result = strtok(NULL, ";"); 
    } 

Me da salida:

1,12
7,19
6,4
8,19
2,2

OK, genial. Pero cuando trato de 'strtok' (estoy usando este método para la división) así:

result = strtok(result, ";"); 

while(result != NULL) { 
    //printf("%s\n", result); 
    help = strtok(result, ",");  
    while(help != NULL) { 
     printf("<%s>", help); 
     help = strtok(NULL, ","); 
    } 

    result = strtok(NULL, ";"); 
} 

solo me dan "< 1>, < 12>" como que hay un solo juego en este conjunto de números No entiendo dónde está el resto de los números. En lugar de ello, la salida debe ser: < 1>, < 12>, < 7>, < 19>, < 6>, < 4>, < 8>, < 19>, < 2>, < 2>. ¿Podría alguien dar una solución, cómo obtener CADA número de cada conjunto de este conjunto de números. Tal vez hay otros métodos o estoy haciendo algo mal :)

¡Gracias!

Respuesta

2

char * strtok (char * str, const char * delim); (desde páginas man)
El argumento delim especifica un conjunto de caracteres que delimitan los tokens en la cadena analizada. La persona que llama puede especificar diferentes cadenas en delim en llamadas sucesivas que analizan la misma cadena.

lo tanto, utilizar tanto ; y , como delimitador para obtener todos los números.

//this will delimit result whenever ";" or "," is found 
result = strtok(result, ";,"); 

while(result != NULL) { 
    printf("%s\n", result); 
    result = strtok(NULL, ";,"); 
} 
1

El primer strtok divide el original en varias cadenas con terminación nula. El segundo strtok solo se aplica a la primera de estas cadenas: se detiene en el primer terminador nulo creado por la primera llamada strtok. Debe llamar al segundo código strtok para CADA cadena creada por la primera.

5

Además de lo que Neil señaló con respecto a la modificación de la cadena original, la función strtok() no está diseñada para ser utilizada de forma anidada como usted describe. Es posible que desee investigar la función strtok_r(), o evitar el uso de la familia strtok* en conjunto.

+0

+1, para señalar la limitación anidada. – codaddict

0

C strtok es bastante malo en el sentido de que modifica la cadena fuente, insertando NULL en lugar de su separador. Por lo tanto, su segundo ciclo se detiene cuando alcanza el valor NULL insertado por el ciclo externo. Lo que desea es guardar los punteros en su ; -cadenas separadas en otro lugar, y luego strtok cada uno de ellos por separado.

O, si desea utilizar bucles anidados, see here.

+0

Wow. ¡Gracias chicos! ¡Funciona genial! Nunca pensé que fuera tan simple. – Dmitri

0

Como otros han señalado, strtok() no es reentrante - mantiene el estado interno de la cadena que está analizando, por lo que no se puede utilizar para analizar dos cadenas diferentes simultáneamente (lo que significa dos valores distintos de NULL para su primer argumento, entonces tu situación cuenta).

Si tiene la versión de reentrada strtok_r() disponible, puede cambiar el código para usarlo de esta manera:

char *st_result, *st_help; 
result = strtok_r(result, ";", &st_result); 

while (result) { 
    printf("[%s]", result); 
    help = strtok_r(result, ",", &st_help);  
    while (help) { 
     printf("<%s>", help); 
     help = strtok_r(NULL, ",", &st_help); 
    } 

    result = strtok_r(NULL, ";", &st_result); 
}