如何检查 C++ 字符串是否为 int?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2844817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I check if a C++ string is an int?
提问by user342231
When I use getline
, I would input a bunch of strings or numbers, but I only want the while loop to output the "word" if it is not a number.
So is there any way to check if "word" is a number or not? I know I could use atoi()
for
C-strings but how about for strings of the string class?
当我使用时getline
,我会输入一堆字符串或数字,但我只希望 while 循环输出不是数字的“单词”。那么有没有办法检查“单词”是否是数字?我知道我可以atoi()
用于 C 字符串,但是对于字符串类的字符串呢?
int main () {
stringstream ss (stringstream::in | stringstream::out);
string word;
string str;
getline(cin,str);
ss<<str;
while(ss>>word)
{
//if( )
cout<<word<<endl;
}
}
回答by paercebal
Another version...
另一个版本...
Use strtol
, wrapping it inside a simple function to hide its complexity :
使用strtol
,将其包装在一个简单的函数中以隐藏其复杂性:
inline bool isInteger(const std::string & s)
{
if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false;
char * p;
strtol(s.c_str(), &p, 10);
return (*p == 0);
}
Why strtol
?
为什么strtol
?
As far as I love C++, sometimes the C API is the best answer as far as I am concerned:
就我喜欢 C++ 而言,有时 C API 就我而言是最好的答案:
- using exceptions is overkill for a test that is authorized to fail
- the temporary stream object creation by the lexical cast is overkill and over-inefficient when the C standard library has a little known dedicated function that does the job.
- 对于被授权失败的测试,使用异常是过度的
- 当 C 标准库有一个鲜为人知的专用函数来完成这项工作时,由词法转换创建的临时流对象是过度杀伤和效率低下的。
How does it work ?
它是如何工作的 ?
strtol
seems quite raw at first glance, so an explanation will make the code simpler to read :
strtol
乍一看似乎很原始,因此解释将使代码更易于阅读:
strtol
will parse the string, stopping at the first character that cannot be considered part of an integer. If you provide p
(as I did above), it sets p
right at this first non-integer character.
strtol
将解析字符串,在第一个不能被视为整数一部分的字符处停止。如果您提供p
(如我上面所做的那样),它会设置p
在第一个非整数字符处。
My reasoning is that if p
is not set to the end of the string (the 0 character), then there is a non-integer character in the string s
, meaning s
is not a correct integer.
我的推理是,如果p
没有设置为字符串的结尾(0 字符),那么字符串中有一个非整数字符s
,意思s
是不是一个正确的整数。
The first tests are there to eliminate corner cases (leading spaces, empty string, etc.).
第一个测试是为了消除极端情况(前导空格、空字符串等)。
This function should be, of course, customized to your needs (are leading spaces an error? etc.).
当然,此功能应该根据您的需要进行定制(前导空格是错误吗?等)。
Sources :
来源:
See the description of strtol
at: http://en.cppreference.com/w/cpp/string/byte/strtol.
请参阅strtol
以下网址的说明:http: //en.cppreference.com/w/cpp/string/byte/strtol。
See, too, the description of strtol
's sister functions (strtod
, strtoul
, etc.).
见,也的描述strtol
的姐姐函数(strtod
,strtoul
等)。
回答by Ferdinando Randisi
The accepted answer will give a false positive if the input is a number plus text, because "stol" will convert the firsts digits and ignore the rest.
如果输入是数字加文本,则接受的答案将给出误报,因为“stol”将转换第一位数字并忽略其余数字。
I like the following version the most, since it's a nice one-liner that doesn't need to define a function and you can just copy and paste wherever you need it.
我最喜欢下面的版本,因为它是一个很好的单行代码,不需要定义一个函数,你可以直接复制粘贴到任何你需要的地方。
#include <string>
...
std::string s;
bool has_only_digits = (s.find_first_not_of( "0123456789" ) == std::string::npos);
EDIT: if you like this implementation but you do want to use it as a function, then this should do:
编辑:如果你喜欢这个实现,但你确实想将它用作函数,那么应该这样做:
bool has_only_digits(const string s){
return s.find_first_not_of( "0123456789" ) == string::npos;
}
回答by Karl von Moor
You might try boost::lexical_cast
. It throws an bad_lexical_cast
exception if it fails.
你可以试试boost::lexical_cast
。bad_lexical_cast
如果失败则抛出异常。
In your case:
在你的情况下:
int number;
try
{
number = boost::lexical_cast<int>(word);
}
catch(boost::bad_lexical_cast& e)
{
std::cout << word << "isn't a number" << std::endl;
}
回答by Mike DeSimone
If you're just checking if word
is a number, that's not too hard:
如果你只是检查是否word
是一个数字,那并不太难:
#include <ctype.h>
...
...
string word;
bool isNumber = true;
for(string::const_iterator k = word.begin(); k != word.end(); ++k)
isNumber &&= isdigit(*k);
Optimize as desired.
根据需要进行优化。
回答by cmo
Use the all-powerful C stdio/string functions:
使用全能的 C stdio/string 函数:
int dummy_int;
int scan_value = std::sscanf( some_string.c_str(), "%d", &dummy_int);
if (scan_value == 0)
// does not start with integer
else
// starts with integer
回答by Jacob
Ok, the way I see it you have 3 options.
好的,在我看来,您有 3 个选择。
1: If you simply wish to check whether the number is an integer, and don't care about converting it, but simply wish to keep it as a string and don't care about potential overflows, checking whether it matches a regex for an integer would be ideal here.
1:如果您只是想检查数字是否为整数,而不关心转换它,而只想将其保留为字符串而不关心潜在的溢出,请检查它是否与正则表达式匹配整数在这里是理想的。
2: You can use boost::lexical_cast and then catch a potential boost::bad_lexical_cast exception to see if the conversion failed. This would work well if you can use boost and if failing the conversion is an exceptional condition.
2:您可以使用 boost::lexical_cast ,然后捕获潜在的 boost::bad_lexical_cast 异常以查看转换是否失败。如果您可以使用 boost 并且转换失败是一种特殊情况,那么这将很有效。
3: Roll your own function similar to lexical_cast that checks the conversion and returns true/false depending on whether it's successful or not. This would work in case 1 & 2 doesn't fit your requirements.
3:滚动你自己的类似于 lexical_cast 的函数,它检查转换并根据它是否成功返回真/假。如果 1 和 2 不符合您的要求,这将起作用。
回答by James
You can use boost::lexical_cast
, as suggested, but if you have any prior knowledge about the strings (i.e. that if a string contains an integer literal it won't have any leading space, or that integers are never written with exponents), then rolling your own function should be both more efficient, and not particularly difficult.
您可以boost::lexical_cast
按照建议使用,但是如果您对字符串有任何先验知识(即,如果字符串包含整数文字,则它不会有任何前导空格,或者整数永远不会用指数书写),然后滚动您自己的函数应该既高效又不特别难。
回答by Nicolas Viennot
template <typename T>
const T to(const string& sval)
{
T val;
stringstream ss;
ss << sval;
ss >> val;
if(ss.fail())
throw runtime_error((string)typeid(T).name() + " type wanted: " + sval);
return val;
}
And then you can use it like that:
然后你可以这样使用它:
double d = to<double>("4.3");
or
或者
int i = to<int>("4123");
回答by Jahid
I have modified paercebal's methodto meet my needs:
我修改了paercebal的方法以满足我的需要:
typedef std::string String;
bool isInt(const String& s, int base){
if(s.empty() || std::isspace(s[0])) return false ;
char * p ;
strtol(s.c_str(), &p, base) ;
return (*p == 0) ;
}
bool isPositiveInt(const String& s, int base){
if(s.empty() || std::isspace(s[0]) || s[0]=='-') return false ;
char * p ;
strtol(s.c_str(), &p, base) ;
return (*p == 0) ;
}
bool isNegativeInt(const String& s, int base){
if(s.empty() || std::isspace(s[0]) || s[0]!='-') return false ;
char * p ;
strtol(s.c_str(), &p, base) ;
return (*p == 0) ;
}
Note:
笔记:
- You can check for various bases (binary, oct, hex and others)
- Make sureyou don't pass
1
, negative value or value>36
as base. - If you pass
0
as the base, it will auto detect the base i.e for a string starting with0x
will be treated as hex and string starting with0
will be treated as oct. The characters are case-insensitive. - Any white space in string will make it return false.
- 您可以检查各种基数(二进制、八进制、十六进制等)
- 制作确保你不及格
1
,负值或价值>36
为基础。 - 如果您
0
作为基数传递,它将自动检测基数,即以 开头的字符串0x
将被视为十六进制,而以 开头的字符串0
将被视为八进制。字符不区分大小写。 - 字符串中的任何空格都会使其返回 false。
回答by Phidelux
Since C++11 you can make use of std::all_ofand ::isdigit:
从 C++11 开始,您可以使用std::all_of和::isdigit:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string_view>
int main([[maybe_unused]] int argc, [[maybe_unused]] char *argv[])
{
auto isInt = [](std::string_view str) -> bool {
return std::all_of(str.cbegin(), str.cend(), ::isdigit);
};
for(auto &test : {"abc", "123abc", "123.0", "+123", "-123", "123"}) {
std::cout << "Is '" << test << "' numeric? "
<< (isInt(test) ? "true" : "false") << std::endl;
}
return 0;
}
Check out the result with Godbolt.
使用Godbolt查看结果。