使用 do-while 循环计算字符串中的字符、单词和行 | C++
Counting characters, words and lines in a string using a do-while loop | 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 %d\n", characters);
printf("The number of words is %d\n", words);
printf("The number of newlines is %d\n", 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 %d\n", characters);
printf("The number of words is %d\n", words);
printf("The number of newlines is %d\n", newlines);
return 0;
}
问题:
您正在尝试做的事情是完全反自然的,没有任何意义。您显示的情况应该使用 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
。
此外,考虑到这解决了您要求的问题,但是如果有相邻的空格或字符串为空,您的代码本身将无法计算单词的数量。
附加信息:
using namespace std;
被认为是 bad practice 在这里你甚至不需要它,因为你没有在 std
命名空间中使用任何东西。
- 您包括了
<string>
和 <typeinfo>
,但两者都没有使用。
发布的 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
。然而,尽管如此,并且在不解决代码中的其他问题(例如评论中提到的问题)的情况下,您可以简单地通过给 'control variable' 一个初始的 'dummy' 值来更改许多这样的循环循环内没有影响。在您的情况下,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-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 %d\n", characters);
printf("The number of words is %d\n", words);
printf("The number of newlines is %d\n", 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 %d\n", characters);
printf("The number of words is %d\n", words);
printf("The number of newlines is %d\n", newlines);
return 0;
}
问题:
您正在尝试做的事情是完全反自然的,没有任何意义。您显示的情况应该使用 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
。
此外,考虑到这解决了您要求的问题,但是如果有相邻的空格或字符串为空,您的代码本身将无法计算单词的数量。
附加信息:
using namespace std;
被认为是 bad practice 在这里你甚至不需要它,因为你没有在std
命名空间中使用任何东西。- 您包括了
<string>
和<typeinfo>
,但两者都没有使用。
发布的 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
。然而,尽管如此,并且在不解决代码中的其他问题(例如评论中提到的问题)的情况下,您可以简单地通过给 'control variable' 一个初始的 'dummy' 值来更改许多这样的循环循环内没有影响。在您的情况下,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!!!
但是请注意,真正实现的所有这些都是通过循环添加一个额外的运行,没有任何目的。