首页 > 解决方案 > 在最后输入非数字值后如何退出while cin循环?

问题描述

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

输入: 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 << ", ";
        }
    }
}

标签: c++loopswhile-loopcin

解决方案


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

由于似乎希望在一行上一次输入所有数据并在事后处理它,因此该代码更加复杂。所以我只是阅读了使用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';
}

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


推荐阅读