2010-02-15 27 views
6

strtok() ile bir dosyadaki sözcüklerin sayısını saymaya çalışıyorum.Beklenmeyen strtok() davranışı

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

Bu, sonsuz bir döngüye neden olur. Niye ya?

+0

'fgets (Sline, STRMAX, fptr) kullanmak' 'yok STRMAX-1 ' – user102008

cevap

8

İki kez aramanız gerekiyor, ikinci kez NULL değerini strtok'a geçirmeniz gerekiyor.

yerine:

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

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

Edit yapın: Tam kaynak:

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

girişinizi dosyasıyla, ben 16

olarak sonuç almak Düzenle # 2: Kaynağınızı değiştirme:

#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; 
} 
aynı sonucu elde - bu arada 16.

+0

doğru sözcük sayısını temsil etmez bu metin dosyamda, anlatabildiğim kadarıyla. – Pieter

+1

@Pieter: 'strtok' kelimesini ikinci kez aramanız gerekiyor. İşte böyle çalışır. Ve ilk parametre ikinci çağrı için (genellikle bir döngüde sarılmış) 'NULL' olmalıdır. Sayaç artışını yeniden düzenlemeniz gerekebilir. Gönderdiğim kodun yalnızca strtok’u nasıl aradığını göstermesi amaçlandı. – dirkgently

+0

@Pieter "anlayabildiğim kadarıyla" biraz belirsiz geri bildirim, bilinen bir kelime sayımı olan bir metin dosyasıyla deneyin ve çözümün işe yarayıp yaramadığını doğrulamak için kullanın. –