如何在最后输入非数值后退出 while cin 循环?

How to exit while cin loop after entering a non-numeric value at the very end?

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

Input: 4 55 6 2 1g // pressing enter here will make it go to the next line, and does not break the while-loop

它通常是如何工作的:

Input: 4 55g 6 2 1 // If I press enter here, it will ignore the "g" and print the number elements from the vector, separated by a comma, which is what I want, but this does not happen if the "g" is at the very end

Output: 4, 55, 6, 2, 1

问题仅在于,当我在末尾而不是在元素之间输入非数字输入时。最后按space也是问题

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

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

这段代码比较复杂,因为它似乎希望在一行中一次输入所有数据并在事后处理它。因此,我只是阅读了使用 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';
}

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