我似乎陷入了我正在上课的字符计数程序的无限循环。请看一下,让我知道我需要改进的地方。我已经在这件事上工作了很长一段时间并继续遇到同样的情况。感谢。
#include <iostream>
#include <ctype.h>
using namespace std;
int WordLength();
void DisplayCount(int wordCount[]);
int main()
{
int L;
int Num_of_Char[16]={0};
cout<<"Please enter some text:\n";
L=WordLength();
while (L)
{
L=WordLength();
Num_of_Char[L]+=1;
}
DisplayCount(Num_of_Char);
}
/***************************************WordLength*******************************************
* Action: Analyzes the text that has been entered and decides what is and isn't *
* a word (mainly by separating words by whitespaces and not accepting *
* most punctuation as part of a word with the exception of hyphens which *
* carry a partial word to the next line as well as apostrophes. *
* *
* Parameters: *
* IN: *
* *
* OUT: *
* *
* *
* Returns: The length of each word. *
* *
* Precondition: *
*********************************************************************************************/
int WordLength()
{
char ch;
int End_Of_Word=0, Length=0;
ch=cin.get();
while((!cin.eof())||(!End_Of_Word))
{
while (!isspace(ch)) //Spaces are delimeters of words
{
if(isalnum(ch)) //if current character is a alpha numeric character it is counted as part of the word
{
++Length;
cin.get(ch);
}
if ((ch=='\'')&&(isalnum(cin.peek()))) //apostrophes are counted as part of the word
{
++Length;
}
if ((ch=='-')&&(isalnum(cin.peek()=='\n'))) //the hyphen as part of the word if followed by newline
{
++Length;
}
if((isspace(ch))||(ispunct(ch))||(ch=='\n'))
{
++End_Of_Word;
}
}
}
return Length;
}
/***************************************DisplayCount*****************************************
* Action: Displays how many words have a specific character count between 1 and *
* 15 characters. Then displays the average word character size. *
* *
* Parameters: *
* IN: wordArray, which points to the array that holds the count of each word's*
* character size. *
* *
* OUT: Displays the array contents in a grid style as well as an average *
* word size based on the contents of the array. *
* *
* Returns: *
* *
* Precondition: wordArray points to an int array *
*********************************************************************************************/
void DisplayCount(int wordArray[])
{
double sum = 0;
cout<<"\tWord Length\t\t"<<"Frequency\n";
cout<<"\t-----------\t\t"<<"---------\n";
for(int i=1; i<16; i++)
{
cout<<"\t "<<i<<"\t\t\t "<<wordArray[i]<<endl; //Displays the contents of each element
sum+=(i*wordArray[i]); //Keeps a running total of contents of array
}
cout<<"\tAverage word length: "<<sum/(15)<<endl; //Displays the average word length
}
答案 0 :(得分:1)
仅在某些条件下输入字符才能确保在其他情况下不会这样做。
例如,在代码中
while (!isspace(ch)) //Spaces are delimeters of words
{
if(isalnum(ch)) //if current character is a alpha numeric character it is counted as part of the word
{
++Length;
cin.get(ch);
}
如果ch
不是空格,那么外部循环将继续迭代,如果恰好ch
不是字母数字,那么cin.get
将不会被执行,然后去到外循环的下一次迭代,依此类推。
了解在这种情况下发生的事情的好方法是在源代码级调试器中运行程序。 Windows中的Visual Studio有一个非常好的。然后只需单步执行程序执行,并注意每个步骤正在发生的事情。
一个不相关但重要的事项:isalnum
等C字符分类函数不接受EOF
以外的否定参数。因此,对于国际使用,具有char
值的简单调用通常会具有未定义的行为,并且可能会在调试版本中使程序崩溃。因此,始终将char
实际参数投射到unsigned char
。
另一个不相关但重要的问题:void main
是非标准的,会导致您的程序被许多编译器(包括g ++)拒绝,并且只比int main
更多地输入一个字符。换句话说,写void main
是非常愚蠢的。 AFAIK唯一能做这件事的专业人员是一些(或许是大多数)微软员工,原因不明 - 但这意味着您可能会遇到void main
,例如在Visual Studio生成的代码中。