计算c中段落中的句子数量

时间:2014-02-02 16:31:44

标签: c while-loop char words text-segmentation

作为课程的一部分,我必须使用Turbo C学习C(不幸的是)。

我们的老师要求我们制作一段代码来计算一个段落中的字符,单词和句子的数量(仅使用printf,getch()和while循环...他不希望我们使用任何其他命令)。这是我写的代码:

#include <stdio.h>
#include <conio.h>

void main(void)  
{  
clrscr();  
int count = 0;  
int words = 0;  
int sentences = 0;  
char ch;

while ((ch = getch()) != '\n')
{
    printf("%c", ch);
    while ((ch = getch()) != '.')
    {
        printf("%c", ch);
        while ((ch = getch()) != ' ')
        {
            printf("%c", ch);
            count++;
        }
        printf("%c", ch);
        words++;
    }
    sentences++;
}

printf("The number of characters are %d", count);
printf("\nThe number of words are %d", words);
printf("\nThe number of sentences are %d", sentences);
getch();
   }

它确实有效(至少计算字符和单词的数量)。但是,当我编译代码并在控制台窗口中检查时,我无法让程序停止运行。它应该在我输入回车键后立即结束。那是为什么?

7 个答案:

答案 0 :(得分:4)

这里有解决问题的方法:

#include <stdio.h>
#include <conio.h>

void main(void)
{
    clrscr();  
    int count = 0;  
    int words = 0;  
    int sentences = 0;  
    char ch;

    ch = getch();
    while (ch != '\n')
    {
        while (ch != '.' && ch != '\n')
        {
            while (ch != ' ' && ch != '\n' && ch != '.')
            {
                count++;
                ch = getch();
                printf("%c", ch);
            }
            words++;
            while(ch == ' ') {
                ch = getch();
                printf("%c", ch);
            }
        }
        sentences++;
        while(ch == '.' && ch == ' ') {
           ch = getch();
           printf("%c", ch);
        }
    }

    printf("The number of characters are %d", count);
    printf("\nThe number of words are %d", words);
    printf("\nThe number of sentences are %d", sentences);
    getch();
}

你的代码的问题是最里面的while循环消耗了所有的字符。每当你进入那里并键入一个点或换行符时它就会停留在该循环中,因为ch与空白不同。但是,当你从最里面的循环退出时,你可能会在第二个循环中停留,因为ch将是一个空白,因此总是与'。'不同。和'\ n'。因为在我的解决方案中,你只在最里面的循环中获得一个字符,在其他循环中你需要“吃掉”空白和点以继续使用其他字符。

在两个内部循环中检查这些条件使代码工作。 请注意,我删除了一些打印件。

希望它有所帮助。

编辑:我添加了指令来打印您键入的内容以及在句子++之后的while循环中的最后一次检查以检查空白,否则它将计算一个单词。

答案 1 :(得分:1)

我认为问题是因为你的外部while循环的条件。它会在找到一个循环终止时检查换行符'\ n'。您可以尝试在具有以下条件的while循环中包含代码

  

而((C =的getchar())!= EOF)

当用户按下Ctrl + z

时,这将停止输入

希望这会有所帮助..

答案 2 :(得分:1)

您可以使用while语句轻松实现if语句:

bool flag = true;
while(IF_COND && flag)
{
    //DO SOMETHING
    flag = false;
}

只需将其插入使用if语句的简单解决方案中。

例如:

#include <stdio.h>
#include <conio.h>

void main(void)  
{  
    int count = 0;  
    int words = 1;  
    int sentences = 1;  
    char ch;

    bool if_flag;

    while ((ch = getch()) != '\n')
    {
        count++;
        if_flag = true;
        while (ch==' ' && if_flag)
        {
            words++;
            if_flag = false;
        }
        if_flag = true;
        while (ch=='.' && if_flag)
        {
            sentences++;
            if_flag = false;
        }
    }

    printf("The number of characters are %d", count);
    printf("\nThe number of words are %d", words);
    printf("\nThe number of sentences are %d", sentences);
    getch();
}

答案 3 :(得分:1)

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

int main(void){

int sentence=0,characters =0,words =0,c=0,inside_word = 0,temp =0;
// while ((c = getchar()) != EOF) 
while ((c = getchar()) != '\n') {
   //a word is complete when we arrive at a space after we 
  // are inside a word or when we reach a  full stop

    while(c == '.'){
        sentence++;
        temp = c;
        c = 0;
    }
     while (isalnum(c)) {
        inside_word = 1;
        characters++;
        c =0;
    }
    while ((isspace(c) || temp == '.') && inside_word == 1){
        words++;
        inside_word = 0;
        temp = 0;
        c =0;
    }
}
printf(" %d   %d   %d",characters,words,sentence);
return 0;
}

这应该这样做,

isalnum检查这封信是否是字母数字,如果是字母或数字,我不希望在这个程序中我的句子中有随机的ascii字符。

isspace,名称为空格检查

你需要ctype.h头。或者你可以加入

   while(c == ' ') and whie((c>='a' && c<='z') || (c >= 'A' && c<='Z') 

如果你不想使用isalpace和isalnum,你的选择,但它会不那么优雅:)

答案 4 :(得分:1)

int ch;
int flag;
while ((ch = getch()) != '\r'){
    ++count;
    flag = 1;
    while(flag && (ch == ' ' || ch == '.')){
        ++words;//no good E.g Contiguous space, Space at the beginning of the sentence
        flag = 0;;
    }
    flag = 1;
    while(flag && ch == '.'){
        ++sentences;
        flag=0;
    }
    printf("%c", ch);
}
printf("\n");

答案 5 :(得分:0)

代码的问题在于您使用每个循环中的字符。 a'\ n'将由扫描句子单词的循环消耗,因此外循环将永远不会看到它。

以下是您问题的可能解决方案:

int sentences = 0;
int words = 0;
int characters = 0;

int in_word = 0; // state of our parser

int ch;
do
{
    int end_word = 1; // consider a word wil end by default
    ch = getch();
    characters++; // count characters
    switch (ch)
    {
    case '.':
        sentences++; // any dot is considered end of a sentence and a word
        break;
    case ' ': // a space is the end of a word
        break;
    default:
       in_word = 1;  // any non-space non-dot char is considered part of a word
       end_word = 0; // cancel word ending
    }

    // handle word termination
    if (in_word and end_word) 
    {
        in_word = 0;
        words++;
    }

} while (ch != '\n');

这些解析问题的一般方法是编写一个有限状态机,一次读取一个字符并对该字符可以触发的所有可能转换作出反应。

在这个例子中,机器必须记住它当前是否正在解析一个单词,这样只有在第一次遇到终止空格或点时才计算一个新单词。

这段代码使用开关来简洁。您可以将其替换为if ... else if sequence以取悦您的老师:)。

如果你的老师强迫你只使用while循环,那么你的老师做了一件蠢事。没有其他条件表达式的等效代码将更重,更难以理解和冗余。

由于有些人认为这很重要,所以这是一个可能的解决方案:

int sentences = 0;
int words = 0;
int characters = 0;

int in_word = 0; // state of our parser
int ch;

// read initial character
ch = getch();

// do it with only while loops
while (ch != '\n')
{
    // count characters
    characters++;

    // count words
    while (in_word)
    {
        in_word = 0;
        words++;
    }

    // skip spaces
    while (ch == ' ')
    {
        ch = -1;
    }

    // detect sentences
    while (ch == '.')
    {
        sentences++;
        ch = -1;
    }

    // detect words
    while ((ch != '\n')
    {
        word_detected = 1;
        ch = -1;
    }

    // read next character
    ch = getch();
}

基本上,您可以将if (c== xxx) ...替换为while (c== xxx) { c = -1; ... }while是一种人为的,受到尊重的编程方式。

锻炼不应该促进愚蠢的做事方式,恕我直言 这就是为什么我怀疑你误解了老师的问题 显然,如果你可以使用if循环,你也可以使用while语句。

尝试仅使用{{1}}循环执行此练习是徒劳的,并且会导致与实际解析器代码一样少或根本无关。

答案 6 :(得分:0)

所有这些解决方案都不正确。解决此问题的唯一方法是创建一个使用 N 自然 L 语言 P 处理并非易事。

输入:

“这是关于Turing机器的一段。AllanTuring博士发明了Turing机器。它解决了一个需要解决0.1%的变化的问题。”

结帐OpenNLP

https://sourceforge.net/projects/opennlp/

http://opennlp.apache.org/