visual使用do-while循环|C++计算字符串中的字符、单词和行



我正在尝试将一个对字符串中的字符、单词和行进行计数的while循环转换为do-while循环。

这是我的while循环:

#include <stdio.h>
#include <string>
#include <typeinfo>
using namespace std;
int main()
{
int c;
int characters = 0;
int words = 1;
int newlines = 0;
printf("Input a string.  Press enter, then ctrl+Z, then enter once more to end string.n");
while ((c = getchar()) != EOF)
{
if (c >= 'a' && c <= 'z' || c>= 'A' && c<= 'Z')
characters++;
else if (c == ' ')
words++;
else if (c == 'n')
newlines++;
}
printf("The number of characters is %dn", characters);
printf("The number of words is %dn", words);
printf("The number of newlines is %dn", newlines);

return 0;
}

几个小时以来,我一直在尝试使用do-while循环重复上述过程,但没有成功。

以下是我目前所拥有的:

#include <stdio.h>
#include <string>
#include <typeinfo>
using namespace std;  
int main()
{
int c;
int characters = 0;
int words = 0;
int newlines = 0;
printf("Input a string.  Press enter, then ctrl+Z, then enter once more to end string.n");

do 
{
c = getchar();
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
characters++;
else if (c == ' ')
words++;
else if (c == 'n')
newlines++;
} while (c = getchar() != EOF);

printf("The number of characters is %dn", characters);
printf("The number of words is %dn", words);
printf("The number of newlines is %dn", newlines);
return 0;
}

发布的do-while循环有两个主要问题。

第一种情况是,您正在读取两个字符,但在循环的每次迭代中只处理一个字符。

第二个问题是while (c = getchar() != EOF)没有做你希望它做的事情。由于运算符的优先级,这相当于while (c = (getchar() != EOF))

do 
{
c = getchar(); // OK the first time, not after that.
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
characters++;
else if (c == ' ')
words++;
else if (c == 'n')
newlines++;
} while (c = getchar() != EOF); // This is bad.

即使您使用解决了第二个问题

while ((c = getchar()) != EOF);

它仍然不好,因为这一行有利于检测EOF,但字符被忽略以进行进一步处理。


您必须将do-while循环更改为:

do 
{
c = getchar();
if ( c == EOF )
{
break;
}
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
characters++;
else if (c == ' ')
words++;
else if (c == 'n')
newlines++;
} while (true);

正如您所看到的,这并不是对while循环的改进。从清洁度的角度来看,它比while循环更差。

正如其他人所提到的,您所描述的情况far更适合使用普通的while循环,而不是do ... while。然而,尽管如此,在不解决代码中的其他问题(如注释中提到的问题(的情况下,您可以通过给"控制变量"一个在循环中没有影响的初始"伪"值来更改许多这样的循环。在您的情况下,c的零值很难成为实际输入值,因此您可以使用:

int c = 0; // Give c an initial (non)value.
do 
{
//  c = getchar(); // Remove this line, as it makes two 'reads' per loop!
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
characters++;
else if (c == ' ')
words++;
else if (c == 'n')
newlines++;
} while ((c = getchar()) != EOF); // Note the added parentheses!!!

但请注意,真正实现的是在循环中添加一个额外的运行,而没有任何目的。

问题:

你试图做的事情完全是反自然的,毫无意义。您显示的情况应该使用while循环,而不仅仅是任何循环。

解决方案:

从技术上讲,你仍然可以这样做,但风格非常糟糕

do
{
bool do_end = (c = getchar()) != EOF;
if(do_end)
break;
if ((c >= 'a' && c <= 'z') || (c>= 'A' && c<= 'Z'))
characters++;
else if (c == ' ')
words++;
else if (c == 'n')
newlines++;
} while (true);

在这种情况下,while循环要好得多,所以除非您实际需要,否则不要使用do while

此外,考虑到这解决了您要求的问题,但如果存在相邻空格或字符串为空,则代码本身在计算单词数量时会出现问题。

附加信息:

  1. using namespace std;被认为是一种糟糕的做法,在这里您甚至不需要它,因为您没有在std命名空间中使用任何东西
  2. 您包含了<string><typeinfo>,但并没有同时使用它们中的任何一个

最新更新