【问题标题】:Cannot break loop using cin.get to detect period无法使用 cin.get 中断循环来检测周期
【发布时间】:2016-02-28 09:22:12
【问题描述】:

我第一次使用 cin.get 一次将一个字符抓取到字符串“word”中。但由于某种原因,我无法将句点设置为退出循环命令。

#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <ctype.h>
#include <string>
using namespace std;

bool isAlpha (char ch);
string replace (string ch);
bool sexist (string ch);

int main()
{
    // Exercise 2
    string word = "";
    string sentence = "";
    char next;
    cout << "Type your sentence " << endl;


    while(next != '.')
    {
        while(true)
        {
            cin.get(next);

            if(isAlpha(next)) // If alphabet then add the char to word
            {
                word = word + next;
            }

            if(isAlpha(next) == false) // If not alphabet then put the char back and stop getting input
            {
                cin.putback(next);
                break;
            }
        }


        if(sexist(word)) // If word is sexist, replace word
        {
            word = replace(word);
        }
        sentence = (sentence + " " + word); // Tacking on words to the sentence

        word = ""; // Resetting word
    }

    cout << "Word = " << word << endl;
    cout << "Sentence = " << sentence << endl;



    return 0;
}

bool isAlpha (char ch)
{
    if(isalpha(ch))
    {
        return true;
    }
    else return false;
}

bool sexist (string ch)
{
    if(ch == "he" || ch == "she")
    {
        return true;
    }
    if(ch == "him" || ch == "her")
    {
        return true;
    }
    if(ch == "his" || ch == "hers")
    {
        return true;
    }
    else
    {
        return false;
    }
}
string replace (string ch)
{
    if(ch == "he" || ch == "she")
    {
        ch = "he or she";
    }
    if(ch == "him" || ch == "her")
    {
        ch = "him or her";
    }
    if(ch == "his" || ch == "hers")
    {
        ch = "his or her(s)";
    }
    return ch;
}

为了进一步解释我的代码:我试图一次抓取一个单词,一次抓取一个字符,并将任何“性别歧视”的单词更改为“中性”。抓住这个词后,如果它是性别歧视的我会改变它,如果不是那么我不会改变它,然后将它添加到“句子”字符串中。我希望最后一个带有句点的单词跳出外部 while 循环并转到我的最终输出行。

但是在尝试了不同的循环和不同的代码之后,我无法摆脱那个 while 循环。是因为get命令吗?我对 C++ 非常陌生,所以我可能不了解一些基本规则。我尝试使用 bool 在下一个检测到句点时将外部 while 循环设置为 false。我尝试使用 goto 命令转到循环外的输出。

【问题讨论】:

  • 无法reproduce。当然,我已经修复了未初始化的next
  • 附带说明,使用非性别的他们/他们/他们比使用繁琐的“他或她”更容易。
  • @SamiKuhmonen 是的,这绝对是有道理的,这只是我实验室提示的一部分。我正在学习基础 C++ 课程。

标签: c++ get cin


【解决方案1】:

你的代码有很多问题(除了你的主要问题):

#include <cstdio>
#include <stdio.h>

cstdiostdio.h 的 c++ 版本。两者都包含是错误的——当你需要包含它时坚持第一个,但在这种情况下你不需要,因为你没有在你的代码中使用任何相关的功能......

那么,为什么要包含所有这些标题?你不使用它们中的大多数......你只需要这些:

#include <iostream> // for cout/cin
#include <cctype>  // the c++ version of ctype.h, for std::isalpha
#include <string> // for std::string

也不要使用命名空间标准!如果您需要了解原因,您会在 stackoverflow 中找到许多相关的帖子。

那么,你真的不需要isAplha 函数,你自己的版本只不过是std::isalpha 所以为什么不直接使用它呢?

那么你有这个:

string replace (string ch);
bool sexist (string ch);

首先要注意的是,您是按值传递 std::string 的,在这两种情况下都不应该这样做。在sexist 的情况下,您应该通过引用来传递 const。但是你真的不需要两个不同的函数。你在复制代码,我会做这样的事情:

void replace (std::string& ch) {
    if(ch == "he" || ch == "she")
        ch = "he or she";
    else if(ch == "him" || ch == "her")
        ch = "him or her";
    else if(ch == "his" || ch == "hers")
        ch = "his or her(s)";
}

然后你可以用更惯用的风格重写你的循环,像这样:

  while(next != '.') {
    while(std::cin.get(next)) {
      if(std::isalpha(next))
     word = word + next;
      else { 
       cin.putback(next); 
       break;
      }
    }
    replace(word);
  }

有了这个,如果你只使用只有字母值和句号的输入,你会没事的。您无法逃脱循环的原因是当std::isalpha 为假时,您将放回字符以便下次重新读取它,这将导致您的程序在对std::isalpha 的相同调用之间无限振荡。 . 考虑到空格不是字母字符.. 因此,一旦达到空格,He is. 之类的输入就会一直振荡..

(顺便说一句,一旦我使用了调试器,我在 30 秒内就发现了这个错误。请使用调试器!它将简化您的编码寿命)

为避免这种情况,您需要对程序采用不同的方法。我建议使用getline 来读取行而不是字符,然后解析它们,在您的情况下,您实际上并不需要逐个字符地读取,您也不期望多行输入。暂且不说,我认为期望您的客户以一段时间来终止所有输入句子以使您的程序正常运行是错误的..

【讨论】:

  • 您好 Marinos,我相信您在一周前回答了我的另一个问题,谢谢。你的回答非常……大开眼界。我在我的代码中做了很多事情的原因是因为我的导师要求具体的说明(可能是因为它比大多数人在这个程序中使用的更简单、更基础)。我认为输入 . 会在它认为 isAlpha 为假之前退出循环并放回字符。谢谢,我会尝试你的所有建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-31
  • 1970-01-01
相关资源
最近更新 更多