Unexpected behavior of strtok ()

I am trying to count the number of words in a file using strtok ().

/* * 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; } 

This causes an endless loop. Why?

+6
c strtok
source share
1 answer

You need two calls, the second time you need to pass NULL to strtok .

Instead:

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

do

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

Edit: Full source:

 #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; } 

With your input file, I get the result as 16.

Edit # 2: change source:

 #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; } 

I get the same result - 16.

+8
source share

All Articles