计算给定文本文件的单词数

时间:2015-03-05 23:06:37

标签: c string file

我写了一个程序来计算文本文件中的单词数。它适用于单个文件行,但问题是当我读取具有换行符的文件时,它会给出错误的结果。例如,如果我将myfile.txt读为:

This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.

我的程序将此计为4个字而不是16个。有关如何修复的建议吗?

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

int main(int argc, char* argv[])
{
    FILE* txtFile = NULL; // File Pointer
    int fileNUM = 0; // Data value from file
    char str[1000000];
    int count = 0, i, len, ignoreSpace;

    // Assigns the text file to txtFile
    txtFile = fopen(argv[1], "r");
    if (txtFile == NULL)
    {
        printf("Error opening file"); // Couldnt find .txt file
        return -1; // -1 indicates error
    }

    // Can now use fscanf(inFile, ...) like scanf()
    fgets(str, 1000000, txtFile); 
    len = strlen(str);
    ignoreSpace = 1;
    for (i = 0; i < len; i++)
    {
        if (str[i] == ' ')
        {
            if (!ignoreSpace)
            {       
                count++;
                ignoreSpace = 1;
            }
        }
        else 
        {
            ignoreSpace = 0;
        }
    }
    if (!ignoreSpace)
        count++;

    printf("There are %i word(s) in %s\n", count, argv[1]);

    fclose(txtFile);

    return 0;
}

3 个答案:

答案 0 :(得分:1)

fgets仅在满足第一个换行符或填充缓冲区之前才会读取。

如果你想阅读文件中的所有行,请利用fgets返回NULL的事实,因为BLUEPIXY在他的评论中指出它不能再读取任何内容:

while (fgets(str, 1000000, txtFile))
{
    len = strlen(str);
    ignoreSpace = 1;
    for (i = 0; i < len; i++)
    {
        if (str[i] == ' ')
        {
            if (!ignoreSpace)
            {       
                count++;
                ignoreSpace = 1;
            }
        }
        else 
        {
            ignoreSpace = 0;
        }
    }
    if (!ignoreSpace)
        count++;
}

答案 1 :(得分:1)

fgets(str, 1000000, txtFile);只读取1行,而不是整个文件。

一个简单的解决方案计算一个单词开始的次数。

int ch;
int PreviousWasSpace = 1;
while ((ch = fgetc(txtFile) != EOF) {
  if (isspace(ch) {
    PreviousWasSpace = 1;
  } else {
    if (PreviousWasSpace) count++;
    PreviousWasSpace = 0;
  }
} 

注意:没有行长度限制。单词之间的多个空格不会导致问题。

答案 2 :(得分:0)

这个问题有很多好办法。以下内容使用getline来读取stdin中的行。这是我最喜欢的方法之一。注意:您可以通过添加tab并使用space功能覆盖其他空格字符来替换ctype.hisspace()的支票。以下选择是为了防止需要额外的头文件:

#include <stdio.h>

int main (void) {

    char *line = NULL;  /* pointer to use with getline ()  */
    char *p = NULL;     /* pointer to parse getline return */
    ssize_t read = 0;   /* actual chars read per-line      */
    size_t n = 0;       /* max chars to read (0 - no limit)*/
    int spaces = 0;     /* counter for spaces and newlines */
    int total = 0;      /* counter for total words read    */

    while ((read = getline (&line, &n, stdin)) != -1) 
    {
        /* strip trailing '\n' or '\r' */
        while (line[read-1] == '\n' || line[read-1] == '\r')
            line[--read] = 0;

        spaces = 0;
        p = line;

        if (read > 0) {                   /* read = 0 covers '\n' case (blank line)  */
            while (*p) {                            /* for each character in line      */
                if (*p == '\t' || *p == ' ') {      /* if space,       */
                    while (*p == '\t' || *p == ' ') /* read all spaces */
                        p++;
                    spaces += 1;                    /* consider sequence of spaces 1   */
                } else
                    p++;                            /* if not space, increment pointer */
            }
            total += spaces + 1;                    /* words per-line = spaces + 1     */
        }
    }

    printf ("\n  Total words read: %d\n\n", total);

    return 0;

}

<强>输出

$ ./bin/countwordsfile <dat/captnjack.txt

  Total words read: 16