意外的 strtok() 行为

发布于 2024-08-21 08:36:00 字数 956 浏览 14 评论 0原文

我正在尝试使用 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;
}

这会导致无限循环。为什么?

I'm trying to count the number of words in a file with 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 infinite loop. Why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

趴在窗边数星星i 2024-08-28 08:36:00

您需要两次调用,第二次您需要将 NULL 传递给 strtok

而不是:

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");          
}

编辑:完整源代码:

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

使用您的输入文件,我得到的结果为 16。

编辑#2:修改您的源代码:

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

我得到相同的结果 - 16。

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

Instead of:

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: Modifying your 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文