微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决使用 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 %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 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",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 循环更糟糕。

,

正如其他人所提到的,您所描述的情况更适合使用普通的 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; 被认为是 bad practice,在这里您甚至不需要它,因为您没有使用 std 命名空间中的任何内容。
  2. 您包含了 <string><typeinfo>,但没有同时使用这两者。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。