繁体   English   中英

C字数统计程序

[英]C Word Count program

我正在尝试编写一个程序,该程序将计算文本中的字符,单词和行数,该文本为:

It was a dark and stormy night;
the rain fell in torrents - except
at occasional intervals, when it was
checked by a violent gust of wind
which swept up the streets (for it is
in London that our scene lies),
rattling along the housetops, and fiercely
agitating the scanty flame of the lamps
that struggled against the darkness.

  Edward Bulwer-Lytton's novel Paul Clifford.

我得到的是62而不是64 ,有什么建议吗?

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

int main() {
    int tot_chars = 0;     /* total characters */
    int tot_lines = 0;     /* total lines */
    int tot_words = 0;     /* total words */
    int boolean;
    /* EOF == end of file */
    int n;
    while ((n = getchar()) != EOF) {
        tot_chars++;
        if (isspace(n) && !isspace(getchar())) {
            tot_words++;
        }
        if (n == '\n') {
            tot_lines++;
        }
        if (n == '-') {
            tot_words--;
        }
    }
    printf("Lines, Words, Characters\n");
    printf(" %3d %3d %3d\n", tot_lines, tot_words, tot_chars);

    // Should be 11 64 375
    // rn     is 11 65 375
    return 0;
}

您的代码中存在多个问题:

  • 在测试if (isspace(n) && !isspace(getchar()))您可能会消耗文件中的一个字节,并且无法递增tot_chars ,此外,如果2个单词由2个空格字符分隔,则不会递增tot_words 这导致darkness. Edward将被视为一个单词。
  • 您在看到连字符时将tot_words递减,这是不正确的,因为单词仅由空格分隔。 这导致Bulwer-Lytton's计数为1-1 ,即零。 因此,您只会得到62个单词,而不是64个单词。

  • 较小的一点是,名称n对于从文件中读取的字节是令人困惑的。 通常,它是更合适的名称。 从文件读取的字节的惯用名称为c ,类型正确为int以容纳所有unsigned char值和特殊值EOF

要检测单词边界,应使用状态并在状态更改时更新单词计数:

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

int main(void) {
    int tot_chars = 0;     /* total characters */
    int tot_lines = 0;     /* total lines */
    int tot_words = 0;     /* total words */
    int in_space = 1;
    int c, last = '\n';

    while ((c = getchar()) != EOF) {
        last = c;
        tot_chars++;
        if (isspace(c)) {
            in_space = 1;
            if (c == '\n') {
                tot_lines++;
            }
        } else {
            tot_words += in_space;
            in_space = 0;
        }
    }
    if (last != '\n') {
        /* count last line if not linefeed terminated */
        tot_lines++;
    }

    printf("Lines, Words, Characters\n");
    printf(" %3d %3d %3d\n", tot_lines, tot_words, tot_chars);

    return 0;
}

实际上,现在我认为您必须修改程序,假设单词之间用空格(任何其他空格字符)分隔,并且如果您的文本具有两个或多个空格(任何其他空白字符)以分隔一个空格,则无法以此为基础进行计数一个字。 因为这也将算作单词,(当没有使用任何实际单词时)

我认为您的最后一个if块确实很乱,您正在使用ispunct()来递减tot_words但文本中的单词在其中使用标点符号(不带空格),这意味着它们是单词的一部分。 所以你不应该减少它们。

以前,我认为我们应该只在if块的末尾检查' -'字符,因为它在带有空格的文本的第一段中使用过,但是它还是在小说名称中再次使用而没有任何空格,因此我认为您应该完全忽略last if块并将'-'视为简化逻辑的单词。

我修改了第一个if块,即使给两个或多个空格(任何其他空格字符)来分隔一个单词,它也可以使您的程序防错。

if (isspace(n))  // isspace() checks for whitespace characters '  ', '\t', '\n','\r, so no need to write like this (isspace(n) || n == '\n')
    boolean=0; //outside of word.     
else if(boolean==0){
    tot_words++;
    boolean=1; //inside of word.
 }

 if (n=='\n')
         tot_lines++;

以下两个条件都增加了换行符上的单词数,这意味着每个单词后跟换行符(而不是空格)都被计数两次:

if (isspace(n) || n == '\n'){
     tot_words++;
}
if (n=='\n'){
     tot_lines++;
     tot_words++;
}

如果摆脱|| n == '\\n' || n == '\\n'位,您应该获得正确的计数。

更改

        if (n=='\n'){
                tot_lines++;
                tot_words++;
        }

  if (n=='\n'){
                tot_lines++;
        }

您已经在换行了

            if (isspace(n) || n == '\n'){
                    tot_words++;
            }

因此,有效地使字计数器的增量增加了每行所需的时间。

我检查了您的代码,它正常工作,同时我也得到了所需的输出(总单词数)-似乎该代码已从其原始帖子中进行了编辑

附加输出我在运行代码后得到的输出 在此处输入图片说明

$ ./a.out " a b " "a b c " "a b c d"
s =  a b , words_cnt= 2
 s = a b c , words_cnt= 3
 s = a b c d, words_cnt= 4

$ ./a.out "It was a dark and stormy night;
> the rain fell in torrents - except
......
  Edward Bulwer-Lytton's novel Paul Clifford., words_cnt = 64

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


int
count_words(const char *s)
{
    int i, w;

    for (i = 0, w = 0; i < strlen(s); i++)
    {
        if (!isspace(*(s+i)))
        {
            w++;
            while (!isspace(*(s+i)) && *(s+i) != '\0')
            {
                i++;
            }
        }
    }

    return w;
}

int
main(int argc, const char *argv[])
{
    int i;

    if (argc < 2)
    {
        printf("[*] Usage: %s <str1> <str2> ...\n", argv[0]);
        return -1;
    }

    for (i = 1; i < argc; i++)
    {
        printf("s = %s, words_cnt= %d\n ", argv[i], count_words(argv[i]));
    }

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM