c++ - 在最后输入非数字值后如何退出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 << ", ";
}
}
}
解决方案
您最大的问题是:
- 您在按 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';
}
编辑:我对代码做了一些细微的修改,以消除对所需输出的误解。我把旧代码注释掉了。
推荐阅读
- java - 得到 0 输出而不是正确的输出
- ios - UIPickerView 中显示的数组不正确
- typescript - 打字稿方法装饰器:这是未定义的
- nativescript - Nativescript Vue条件v模板不起作用
- html - 页眉和页脚背景不会拉伸页面的整个宽度
- r - 如何根据dataframe1中的值从dataframe2中提取子集并将所有子集堆叠在R中的一个数据框中?
- r - file.path 函数找不到文件
- swift - 如何修复“无法为类型 'MBMovingGround 调用初始化程序?' 没有参数” swift中的错误
- oracle - 检查我将插入的新行的某些属性是否存在于此表中,如果是,则通过触发器执行某些操作
- javascript - TypeScript 映射类型推断未按预期工作