簡體   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