C - 计算文件中的单词、字符和行数。字数

C - Counting words, characters and lines in file. Character count

我必须用 C 编写代码,输出给定文件中的字符数、行数和单词数。任务看起来很简单,但我真的不确定此时哪里出了问题。

所以,这是代码:

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

int main()
{
    FILE *file;
    char filename[256];
    char ch;
    char prevch;

    int lines=0;
    int words=0;
    int characters=0;

    printf("Enter your filename (don't forget about extension!):\n");
    scanf("%s", filename);

    file=fopen(filename, "r");
    if(file == NULL)
    {
        printf("Cannot open file %s \n", filename);
        exit(0);
    }
    else
    {

        while((ch=fgetc(file))!=EOF)
        {
            if(ch==' ' || ch=='\n' || ch=='\t')
            {
                if(isspace(prevch)==0)
                {
                    words++;
                }
            }
            if(ch=='\n')
            {
                lines++;
            }

            prevch=ch;
            characters++;
        }
    }

    fclose(file);

    if(isspace(prevch)==0)
    {
        words++;
    } 

    printf("Number of characters: %d\n", characters);
    printf("Number of words: %d\n", words);
    printf("Number of lines: %d\n", lines);

    return 0;
}

任务的想法是输出应该与 Linux 中命令 wc 的输出相同。但我完全不知道为什么我的循环会跳过一些字符。我编写代码的方式应该适合计算每个字符,甚至是那些空格。为什么我的程序显示示例文件包含 65 个字符,而 wc 显示 68 个字符?我想也许有一些字符被 fgetc 跳过,但这是不可能的,因为我以前在编写程序将一个文本文件的内容复制到另一个文本文件时使用过该函数,并且一切正常。

顺便问一下,我的字数计算方法正确吗?循环后的条件应确保计算 EOF 之前的最后一个字。我使用 isspace 来确保结尾处不只是一些空格。

谢谢!

"My program shows sample file contains 65 characters, when wc shows 68"

您正在处理 Windows,您的文件是否只有三行?如果是这样,问题是 Windows 将 CRLF 行结尾映射到换行符,因此 3 个 CRLF 对映射到 3 个换行符(仅 LF)结尾,造成了差异。要解决此问题,请以二进制模式打开文件。

没有运行你的代码,我认为你的字数统计代码是可以的。您可以改为使用最初设置为 0(假)的 'in-word' 标志并切换为 true 并在您检测到不是白色的东西时计算一个新词 space 而您不在一个词中。两者都有效;它们略有不同。

此外,请记住 fgetc() 和亲戚 return 是 int,而不是 char。如果将 return 值保存在 char 中,则无法可靠地检测到 EOF,尽管问题的性质取决于普通 char 是有符号还是无符号以及使用的代码集。

如果plain char是unsigned类型,永远检测不到EOF(因为EOF被映射为0xFF,转换成int与EOF比较时为正) .如果普通 char 已签名,如果输入包含代码 0xFF(在 ISO 8859-1 和相关代码集中,即 ÿ - Unicode 术语中带分音符的拉丁文小写字母 Y),您会及早检测到 EOF。但是,有效的 UTF-8 永远不能包含字节 0xFF(也不是 0xC0、0xC1 或 0xF5..0xFF),因此您不应该 运行 陷入这种误解问题——但是您的代码是字节计数而不是字符也在数。

你可以这样做

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

int main()
{
    FILE *file;
    char filename[256];
    char ch;
    char prevch = '[=10=]';

    int lines = 0;
    int words = 0;
    int characters = 0;

    printf("Enter your filename (don't forget about extension!):\n");
    scanf("%s", filename);

    file = fopen(filename, "r");
    if(file == NULL)
    {
        fprintf(stderr, "Cannot open file %s \n", filename);
        exit(-1);
    }

    while((ch = fgetc(file)) != EOF)
    {
        if(isspace(ch))
        {
            if (ch == '\n')
                lines++;
        }else {
            if (prevch == '[=10=]' || isspace(prevch)) 
                words++;
        }

        characters++;
        prevch = ch;  
    }

    fclose(file);

    printf("Number of characters: %d\n", characters);
    printf("Number of words: %d\n", words);
    printf("Number of lines: %d\n", lines);

    return 0;
}