C++ 在整数输入中跳过单个减号或加号
最近,我需要一个简单的程序来对标准输入中出现的所有整数求和,每行一个整数。输入碰巧包含一些未设置的行,其中包含一个减号('-'),以及一些带有垃圾字符的行(将被忽略) 我相信这将是一个微不足道的计划。但事实证明,单减号并没有表现出其他不好的输入。在正常的非整数输入上,设置失败标志,错误输入保留在输入缓冲区中。但是使用一个减号(或加号)设置失败标志,但删除+/-号,导致程序跳过下一个(有效)整数(导致错误和) 我写了一个小测试程序(如下)来分析行为。 上述带有+/-符号的行为是错误还是特性C++ 在整数输入中跳过单个减号或加号,c++,validation,C++,Validation,最近,我需要一个简单的程序来对标准输入中出现的所有整数求和,每行一个整数。输入碰巧包含一些未设置的行,其中包含一个减号('-'),以及一些带有垃圾字符的行(将被忽略) 我相信这将是一个微不足道的计划。但事实证明,单减号并没有表现出其他不好的输入。在正常的非整数输入上,设置失败标志,错误输入保留在输入缓冲区中。但是使用一个减号(或加号)设置失败标志,但删除+/-号,导致程序跳过下一个(有效)整数(导致错误和) 我写了一个小测试程序(如下)来分析行为。 上述带有+/-符号的行为是错误还是特性 #in
#include <iostream>
using namespace std;
int main()
{
string s;
int n;
while (true)
{
n = -4711;
cin >> n;
cerr << (cin.bad() ? "ERROR: badbit is set\n" : "");
cerr << (cin.fail() ? "ERROR: failbit is set\n" : "");
cerr << (cin.eof() ? "ERROR: eofbit is set\n" : "");
if ( cin.bad() || cin.eof() )
break;
if ( cin.fail() )
{
cin.clear();
cin >> s;
cerr << "ERROR: ignored string '" << s
<< "' (integer is '" << n << "')" << endl;
}
else
{
cout << "OK: read integer '" << n << "'" << endl;
}
}
return 0;
}
(我已经解决了我原来的问题,改为读取字符串,并使用C++11 stoi和异常来识别错误的输入。)
编辑:如果有人对我的原始问题的解决方案感兴趣:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int sum = 0;
string n;
while ( cin >> n )
{
try {
sum += stoi(n);
cout << n << endl;
}
catch (exception& e)
{
cerr << e.what() << " ERROR: '" << n << "' is not a number." << endl;
}
}
cout << sum << endl;
return 0;
}
#包括
#包括
使用名称空间std;
int main()
{
整数和=0;
字符串n;
while(cin>>n)
{
试一试{
sum+=stoi(n);
cout这是一项功能。cin
在读取“-”后的空格后才知道输入有误。没有可移植的方法使用iostreams放回多个字符,也没有可移植的方法在cin中查找。因此它被卡住了,必须将“-”保持为读取状态
在读取数据时,最好是自己解析。将所有数据读入字符串,然后自己解析这些字符串,以确定哪些是真实的,哪些是垃圾。这样,你就可以完全控制,而不是与iostreams所做的任何事情作斗争。我会这样做:
#include <locale>
#include <sstream>
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
struct number_only: std::ctype<char> {
number_only() : std::ctype<char>(get_table()) {}
static mask const *get_table() {
static std::vector<mask> rc(table_size, space);
std::fill_n(&rc['0'], 10, digit);
return &rc[0];
}
};
int main() {
std::string input("1 asdf 2 - 3 + 4 qwer 5 ");
std::istringstream x(input);
// use our ctype facet:
x.imbue(std::locale(std::locale(), new number_only));
// initialize vector from the numbers in the file:
std::vector<int> numbers((std::istream_iterator<int>(x)),
std::istream_iterator<int>());
// display what we read:
std::copy(numbers.begin(), numbers.end(),
std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
仅结构编号:std::ctype{
number_only():std::ctype(get_table()){
静态掩码常量*get_table(){
静态标准::向量rc(表大小、空间);
标准::填写(&rc['0',10,数字);
返回&rc[0];
}
};
int main(){
标准::字符串输入(“1 asdf 2-3+4 qwer 5”);
std::istringstream x(输入);
//使用我们的ctype方面:
x、 imbue(std::locale(std::locale(),仅限新编号_));
//根据文件中的数字初始化矢量:
std::向量数((std::istream_迭代器(x)),
std::istreamu迭代器();
//显示我们阅读的内容:
std::copy(numbers.begin(),numbers.end(),
std::ostream_迭代器(std::cout,“\n”);
返回0;
}
不是最简单的解决方案,但我必须说的很有趣!(我以前没有玩过LoalAs)。KM:我不知道,你编写的代码的逻辑几乎近乎荒谬地简单。请考虑这个代码是有效的,没有(显式)条件(如果是,等等),并且仍然比(非功能性)短。问题中的示例。你的是一个很好的解决方案,它在早期阶段排除了不必要的输入。可能非常有效。这就是为什么我认为它很有趣。如果它是直接的或不直接的,当然是非常主观的-取决于你已经知道的,我猜。顺便说一句,我将我的解决方案添加到了我的原始问题中。它没有缓冲区所有可能重要的向量输入。(杰瑞的解决方案可以很容易地重写,以避免向量和求和。)
#include <locale>
#include <sstream>
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
struct number_only: std::ctype<char> {
number_only() : std::ctype<char>(get_table()) {}
static mask const *get_table() {
static std::vector<mask> rc(table_size, space);
std::fill_n(&rc['0'], 10, digit);
return &rc[0];
}
};
int main() {
std::string input("1 asdf 2 - 3 + 4 qwer 5 ");
std::istringstream x(input);
// use our ctype facet:
x.imbue(std::locale(std::locale(), new number_only));
// initialize vector from the numbers in the file:
std::vector<int> numbers((std::istream_iterator<int>(x)),
std::istream_iterator<int>());
// display what we read:
std::copy(numbers.begin(), numbers.end(),
std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}