如何检测转换是否在 c++0x 中失败
How to detect if the conversion failed in c++0x
我尝试执行字符串到整数的转换,如下所示:
#include<iostream>
#include<sstream>
#include<string>
int main(int argc, char ** argv)
{
int i;
char *str = "12a3";
std::stringstream ss;
ss << str;
ss >> i;
std::cout << i << std::endl; //prints 12
}
演示
但结果不是我所期望的。我是Java,所以老实说,我一直在等待抛出一些异常。但事实并非如此。是否可以在没有旧atoi
功能的情况下以安全的方式执行此类转换。
请注意,我C++0x
因此无法使用std::stoi
.
正确的行为。>>
到int
的操作成功,这是正确的。
你必须问一个不同的问题。您真正想要执行的测试是:"成功读取int
后,流中是否还有剩余且尚未处理的字符?
考虑cin
.当你这样做时
int x, y;
std::cin >> x;
std::cin >> y;
它尽可能多地从标准输入读取x
,停在第一个非数字。然后,如果第一个数字后面只有一些空格,那么它将尝试读取空格后面的数字并将该数字存储在 y
中。
所有输入流(无论是cin
还是实例stringstream
)都应包含许多字符串/数字/任何内容。每个>>
都只是尽可能多地读取(成功)。
我知道的最简单的方法。
int main(int argc, char ** argv)
{
std::string num;
long i;
char *str = "12a3";
char * endp;
std::stringstream ss;
ss << str;
ss >> num;
i = strtol(num.c_str(), // string to convert as a C style string,
&endp, //pointer to be updated with character that ended the conversion
10); //base of number conversion
if (*endp != ' ')
{
//didn't read whole string. conversion failed
}
std::cout << i << std::endl; //prints 12
}
您需要测试不成功的流读取和不完整的流读取:
ss >> i;
if (!ss || !ss.eof()) {
throw std::invalid_argument("Could not convert to int");
}
在注释中,我们得出结论,您的目标是确定字符串是否仅由数字的有效表示形式组成。
C 和扩展C++一直专注于流 I/O,因此也专注于类似流的数字转换。 这样做的结果是scanf
、istream >>
、atoi
和strol
都停止在不是有效数字的一部分的第一个字符处。
然后,您的目标是确定输入是否已完全使用,或者是否存在尾随的"垃圾"字符。 最简单的方法是使用 strtol,它将返回指向第一个未使用字符的指针。
char * endptr;
long i = strtol (str, &endptr, 10);
bool valid = *endptr == ' ';
如果您的输入如下所示:"123",这仍然会失败,因为扫描将在"3"后面的空格字符处停止。
如果你的要求是尾随空格是可以接受的,你的代码将需要检查调用后从 *endptr 开始的字符串,以确定它是否是可接受的后缀,或者它可以在执行测试之前修剪输入字符串。
当运算符>>
找到它无法使用的结果时,它会在流上设置failbit
,流本身的计算结果将false
:
if(!(ss >> i)) { // or ss >> i; if(!ss) or if(ss.fail())
// the conversion failed, do whatever you need to here.
ss.clear(); // reset the fail flag so you can read from the stream again
// you can use ss.ignore() to skip bad input if you want to move on to other parts
}
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- arm-linux-gnueabihf-g++ 是否有可靠的 C++0x 支持?
- 是否有任何方法可以将unique_ptr插入C++0x%gcc 4.4.7中的映射中
- 是否有一个简单的方法来实现AutoResetEvent在c++ 0x
- 在c++ 0x中,非静态数据成员初始化式是否覆盖隐式复制构造函数?
- 是否有一个编译时函数/宏来确定c++ 0x结构体是否为POD
- c++ 0x中是否包含完整的增强功能?
- 如何检测转换是否在 c++0x 中失败