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

时间:2017-12-20 08:59:08

标签: c file character lines words

我必须在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跳过了,但是当我编写程序将一个文本文件的内容复制到另一个并且一切正常时,我就不可能使用该函数了。 p>

顺便说一句,我的字数统计解决方案是否正确?循环后的条件应确保计算EOF之前的最后一个单词。我使用了isspace来确保结尾不只有一些空格。

谢谢!

2 个答案:

答案 0 :(得分:2)

  

“我的程序显示示例文件包含65个字符,当wc显示68”

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

如果没有运行代码,我认为你的代码用于计算单词是正常的。您可以改为使用最初设置为0(false)的“in-word”标志并切换为true,并在检测到非空白区域时计算新单词,而不是单词。两者都有效;他们略有不同。

此外,请记住fgetc()和亲属返回int,而不是char。如果将返回值保存在char中,则无法可靠地检测EOF,但问题的性质取决于普通char是否已签名或未签名且代码集是否正在使用中。

如果普通char是无符号类型,则永远不能检测到EOF(因为EOF映射到0xFF,当转换为int以与EOF进行比较时,它是正的)。如果普通char已签名,如果输入包含代码0xFF(在ISO 8859-1和相关代码集中,那是ÿ - 在Unicode术语中带有DIAERESIS的LATIN SMALL LETTER Y),则会提前检测到EOF。但是,有效的UTF-8永远不能包含字节0xFF(也不是0xC0,0xC1,也不是0xF5..0xFF),所以你不应该遇到那个误解释问题 - 但是你的代码是字节计数而不是字符计数。 / p>

答案 1 :(得分:1)

你可以这样做

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

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

    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 == '\0' || 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;
}