如何在最后输入非数值后退出 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';
}
编辑:我对代码做了一些细微的修改,以消除对所需输出的误解。我将旧代码注释掉了。
此代码采用多个整数,并在按下“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';
}
编辑:我对代码做了一些细微的修改,以消除对所需输出的误解。我将旧代码注释掉了。