C字计数程序

C字计数程序,c,word-count,C,Word Count,我正在尝试编写一个程序来计算文本中的字符、单词和行数,文本为: 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 a

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

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;
}
#包括
#包括
#包括
int main(){
int tot_chars=0;/*总字符数*/
int tot_行=0;/*行总数*/
int tot_words=0;/*总字数*/
整数布尔;
/*EOF==文件结尾*/
int n;
而((n=getchar())!=EOF){
tot_chars++;
if(isspace(n)&&!isspace(getchar()){
tot_words++;
}
如果(n=='\n'){
tot_lines++;
}
如果(n='-'){
tot_单词--;
}
}
printf(“行、字、字符”);
printf(“%3d%3d%3d\n”,总计行、总计字、总计字符);
//应该是1164375
//注册护士人数为1165375
返回0;
}

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

if (isspace(n) || n == '\n'){
     tot_words++;
}
if (n=='\n'){
     tot_lines++;
     tot_words++;
}
如果去掉
|n=='\n'
位,则应获得正确的计数。

更改

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

您已经在计算中的新行的单词了

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

所以,实际上,您正在将每行所需的字计数器增加一倍

事实上,现在我认为您必须修改程序,假设单词由空格(任何其他空格字符)分隔,如果您的文本有两个或更多空格(任何其他空格字符)分隔单个单词,那么在此基础上计算将不起作用。因为这也将被算作单词(当没有实际使用的单词时)

我认为您的最后一个
块非常凌乱,您使用
ispunt()
来减少
tot_单词
,但文本中的单词使用标点符号(没有空格),这意味着它们是单词的一部分。所以你不应该减少它们

以前我认为我们应该只检查最后一个
if
块中的“
-”
字符,因为它用于文本的第一段,带有空格,但它也同样用于小说名称,没有空格,因此,我认为你应该完全忽略最后<代码>如果Band,考虑<代码> -'/COD>作为简单逻辑的单词。< /P> 我已经修改了第一个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)&&&!isspace(getchar())
    中,您可能会从文件中消耗一个字节,并且无法增加
    tot_chars
    ,此外,如果两个字之间由两个空格字符分隔,则不会增加
    tot_words
    。这导致
    黑暗。
    Edward
    被算作一个单词
  • 当您看到连字符时,会将
    减为tot_words
    ,这是不正确的,因为单词之间仅用空格分隔。这导致
    Bulwer-Lytton的
    被计算为
    1-1
    ,即零。因此,你只得到62个单词,而不是64个

  • 另一方面,名称
    n
    与从文件中读取的字节混淆。它通常是计数的更合适的名称。从文件读取的字节的惯用名称是
    c
    ,类型正确为
    int
    ,以适应
    无符号字符的所有值加上特殊值
    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;
}
#包括
#包括
内部主(空){
int tot_chars=0;/*总字符数*/
int tot_行=0;/*行总数*/
int tot_words=0;/*总字数*/
_空间中的int=1;
int c,last='\n';
而((c=getchar())!=EOF){
last=c;
tot_chars++;
if(i空间(c)){
in_空间=1;
如果(c=='\n'){
tot_lines++;
}
}否则{
tot_words+=在_空间中;
在_空间中=0;
}
}
如果(最后一个!='\n'){
/*如果换行未终止,则计数最后一行*/
tot_lines++;
}
printf(“行、字、字符”);
printf(“%3d%3d%3d\n”,总计行、总计字、总计字符);
返回0;
}

#包括
#包括
#包括
#包括
int
计数字(常量字符*s)
{
int i,w;
对于(i=0,w=0;i
我的建议是您得到结果时对原始代码的唯一更改,还是您使用问题中的当前代码进行了更改?你是否尝试过调试并逐行查看它在错误的位置递增?你的文本是否还包括作者姓名和小说?是的,所有内容都是“我一直在得到…”@user3516302:你能接受通过单击分数下方的灰色复选标记发布的答案之一吗?谢谢!如此接近,现在显示的是65个单词,而不是64个。如果你包括
我一直得到的
,那么计数应该是
67
。。。代码有缺陷,你只是偶然得到了64个单词,因为连字符和2个mor而漏掉了一个
#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;
}
$ ./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;
}