作为课程的一部分,我必须使用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();
}
它确实有效(至少计算字符和单词的数量)。但是,当我编译代码并在控制台窗口中检查时,我无法让程序停止运行。它应该在我输入回车键后立即结束。那是为什么?
答案 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