【问题标题】:How to exit while cin loop after entering a non-numeric value at the very end?在最后输入非数字值后如何退出while cin循环?
【发布时间】:2020-08-08 02:19:34
【问题描述】:

此代码采用多个整数,并在按下“Enter”键时将其放入一个向量中。输出显示向量内的所有元素;每个元素用逗号分隔。问题是当我在末尾输入字母或空格时,“Enter”键不会退出 while cin 循环。 例如:

Input: 4 55 6 2 1g // 这里按回车键会跳到下一行,不会破坏while循环

它通常是如何工作的:

输入:4 55g 6 2 1 // 如果我在这里按回车,它将忽略“g”并打印向量中的数字元素,用逗号分隔,这是我想要的,但这如果“g”在最后,则不会发生

输出:4、55、6、2、1

问题仅在于,当我在最后输入非数字输入时,而不是在元素之间。最后按空格也会导致问题

int main() {

vector<int> myv;
int value = 0;

while (cin >> value){
    myv.push_back(value);
    if (cin.get() == '\n'){
        break;
    }
}

auto iter = myv.begin();
    while(true){
        cout << *iter;
        ++iter;
        if(iter == myv.end()){
            break;
        }
        else{
            cout << ", ";
        }
    }
}

【问题讨论】:

  • 在你检查是否应该之前,你是在推后。
  • @sweenish 我尝试使用 !cin.fail() ,但同样的问题仍然存在。有什么想法吗?
  • 更好地列出您的要求。整数总是个位数吗?您的第一个 while 循环是无限的也是有道理的。它永远不会失败。 每个 ASCII 字符都可以转换为int。
  • @sweenish 不,整数并不总是个位数。两位数也可以。 Cin 自动按空格分解数字。
  • 你不需要向我解释std::cin。我只是想弄清楚您的实际要求。

标签: c++ loops while-loop cin


【解决方案1】:

您最大的问题是:
- 您在按 Enter 之前输入的字母仍在流中。因此,您的 std::cin.get() 检查不会识别 Enter 键,而是会识别字母。
- 在检查是否应该有之前,你推回了你的向量。那些字母 'g's 将进入你的向量。

此代码更复杂,因为似乎希望在一行上一次输入所有数据并在事后处理它。因此,我只需阅读 using std::getline() 中的行并在函数 break_up() 中处理该总输入。此时,我有一个字符串向量,其中包含所有输入的单独片段,无论是否有效。

最后,检查块的有效性。一旦找到无法完全转换为整数的块,myv 就会停止接收数据。然后打印出来。我用更短的 for 循环替换了你的 while 循环。

如果每条数据都是单独输入并在您进行时检查,那么这个程序会变得容易得多。打破线路的最困难的部分消失了,您可以随时验证并在遇到​​错误数据时准确停止,而不是输入大量数据只是为了发现其中 80% 没有添加。

#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> break_up(std::string line) {
  std::vector<std::string> chunks;

  // Emtpy line check
  if (line.length()) {
    std::string::size_type loc = 0;
    std::string::size_type subStart = 0;
    while (loc != std::string::npos) {
      loc = line.find_first_of(" \t\r\n", loc + 1);
      loc != std::string::npos
          ? chunks.push_back(line.substr(subStart, loc - subStart))
          : chunks.push_back(line.substr(subStart));  // catches last item
      subStart = loc + 1;
    }
  }

  return chunks;
}

int main() {
  std::vector<int> myv;
  std::string values;  // Changed type

  std::getline(std::cin, values);
  std::vector<std::string> chunks = break_up(values);

  for (auto i : chunks) {
    // std::size_t pos;
    try {
      int num = std::stoi(i); // , &pos);
      // if (pos == i.length()) {
        myv.push_back(num);
      // } else {
      //   break;  // Remove this else block to add all valid numbers that
      // }         // were entered
    } catch (...) {
    }  // std::stoi throws two exceptions, don't need to
       // distinguish or take any action. Just don't want the program ending
  }

  // Replaced unnecessarily complicated while loop
  for (unsigned int i = 0; i < myv.size(); ++i) {
    std::cout << myv[i];
    if (i < myv.size() - 1) {
      std::cout << ", ";
    }
  }
  std::cout << '\n';
}

编辑:我对代码做了一些细微的修改,以消除对所需输出的误解。我把旧代码注释掉了。

【讨论】:

  • 如果在两者之间输入非整数,则此代码将不起作用。例如:输入 -> 4 55g 6 2 1。但我感谢您的帮助。
  • 是的。我测试过了。
  • 嗯。我试过了,但是当我输入 4 55g 6 2 1 时,输出只是:4,而不是 4、55、6、2、1。
  • 我明白了。一旦输入了无效字符,我将您所需的输出视为停止。这是一个很容易解决的问题。
猜你喜欢
  • 2019-03-19
  • 2020-09-12
  • 1970-01-01
  • 2019-04-20
  • 2020-11-09
  • 1970-01-01
  • 2013-03-01
  • 2019-08-28
  • 1970-01-01
相关资源
最近更新 更多