2010-02-15 20 views
6

Estoy tratando de contar el número de palabras en un archivo con strtok().Comportamiento strtok inesperado()

/* 
* code.c 
* 
* WHAT 
*  Use strtok() to count the number of words in a file. 
*/ 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define STRMAX 128 

int main() { 
    /* Declarations */ 
    FILE* fptr; 
    int iCntr = 0; 
    char sLine[STRMAX]; 
    char* cPToken; 

    /* Read file */ 
    /* Error handler */ 
    if ((fptr = fopen("/home/ubuntu/Dropbox/Unief/C/H18/Opdr01/Debug/test.txt", "r")) == NULL) { 
     printf("Couldn't read test.txt.\n"); 
     exit(0); 
    } else { 
     while (fgets(sLine, STRMAX-1, fptr) != NULL) {     /* Read line */ 
      while ((cPToken = strtok(sLine, ".,; !?\r\n")) != NULL) { /* Split into words */ 
       iCntr++; 
      } 
     } 
     printf("Number of words: %d\n", iCntr); 
    } 

    /* Always clean up your mess */ 
    fclose(fptr); 
    return 0; 
} 

Esto causa un bucle infinito. ¿Por qué?

+0

por cierto usar 'fgets (sLine, STRMAX, fptr)' 'no STRMAX-1' – user102008

Respuesta

8

Necesita dos llamadas, la segunda vez que necesita pasar NULL a strtok.

En lugar de:

while ((cPToken = strtok(sLine, ".,; !?\r\n")) != NULL) { /* Split into words */ 
       iCntr++; 
} 

hacer

cPToken = strtok(sLine, ".,; !?\r\n"); 
while (cPToken != NULL) { /* Split into words */ 
    iCntr++; /* we have a valid word */ 
    cPToken = strtok(NULL, ".,; !?\r\n");   
} 

Editar: fuente completo:

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

size_t wcount(const char *fname, const char *delim) { 
    char buf[ 512 ]; 
    size_t nw = 0; 
    FILE *fp = fopen(fname, "r"); 
    if (fp) { 
     while (fgets(buf, sizeof buf, fp) != NULL) { 
      for (char *w = strtok(buf, delim); w; w = strtok(NULL, delim)) 
       nw++; 
     } 
     fclose(fp); 
    } 
    return nw; 
} 

int main(int argc, char* argv[]) 
{ 
    printf("%u\n", wcount("C:\\sample.txt", ".,; !?\r\n")); 
    return 0; 
} 

Con el archivo de entrada, me sale el resultado como 16.

Editar # 2: modificando su fuente:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define STRMAX 128 

int main() { 
    /* Declarations */ 
    FILE* fptr; 
    int iCntr = 0; 
    char sLine[STRMAX]; 
    char* cPToken; 

    /* Read file */ 
    /* Error handler */ 
    if ((fptr = fopen("c:\\test.txt", "r")) == NULL) { 
     printf("Couldn't read test.txt.\n"); 
     exit(0); 
    } else { 
     while (fgets(sLine, STRMAX-1, fptr) != NULL) {     /* Read line */ 
      cPToken = strtok(sLine, ".,; !?\r\n"); 
      while (cPToken != NULL) { /* Split into words */ 
       iCntr++; 
       cPToken = strtok(NULL, ".,; !?\r\n"); 
      } 
     } 
     printf("Number of words: %d\n", iCntr); 
    } 

    /* Always clean up your mess */ 
    fclose(fptr); 
    return 0; 
} 

puedo obtener el mismo resultado - 16.

+0

que no representa con precisión el número de palabras en mi archivo de texto, hasta donde yo sé. – Pieter

+1

@Pieter: debe llamar a 'strtok' por segunda vez. Así es como funciona. Y el primer parámetro debe ser 'NULL' para la segunda llamada (que generalmente está envuelto en un bucle). Es posible que deba reorganizar el incremento del contador. El código que publiqué tenía la intención de mostrar cómo llamar a 'strtok' solamente. – dirkgently

+0

@Pieter "por lo que puedo decir" es un poco vago comentario, intente con un archivo de texto con un conteo de palabras conocido y utilícelo para verificar si la solución funciona o no. –

Cuestiones relacionadas