如何将标准::字符串转换为整数
How can I convert a std::string to int?
我想将字符串转换为整数,我的意思不是ASCII代码。
为了快速运行,我们将在等式中作为字符串传递。我们要分解它,正确格式化它并求解线性方程。现在,这么说,我无法将字符串转换为 int。
我知道字符串的格式为 (-5( 或 (25( 等,所以它绝对是一个整数。但是我们如何从字符串中提取它呢?
我想的一种方法是对字符串运行一个 for/while 循环,检查一个数字,提取之后的所有数字,然后查看是否有前导"-",如果有,将 int 乘以 -1。
不过,对于这样一个小问题来说,这似乎有点过于复杂了。有什么想法吗?
在 C++11 中,有一些不错的新函数从 std::string
转换为数字类型。
所以而不是
atoi( str.c_str() )
您可以使用
std::stoi( str )
其中str
是你的号码std::string
.
有适用于所有数字风格的版本: long stol(string)
、float stof(string)
、double stod(string)
,...请参阅 http://en.cppreference.com/w/cpp/string/basic_string/stol
可能的选项如下所述:
1. 斯坎夫((
#include <cstdio>
#include <string>
int i;
float f;
double d;
std::string str;
// string -> integer
if(sscanf(str.c_str(), "%d", &i) != 1)
// error management
// string -> float
if(sscanf(str.c_str(), "%f", &f) != 1)
// error management
// string -> double
if(sscanf(str.c_str(), "%lf", &d) != 1)
// error management
这是一个错误(也由 cppcheck 显示(,因为"在某些版本的 libc 上,没有字段宽度限制的 scanf 可能会因大量输入数据而崩溃">(请参阅此处和此处(。
2. 标准::sto((*
#include <iostream>
#include <string>
int i;
float f;
double d;
std::string str;
try {
// string -> integer
int i = std::stoi(str);
// string -> float
float f = std::stof(str);
// string -> double
double d = std::stod(str);
} catch (...) {
// error management
}
此解决方案简短而优雅,但仅在兼容 C++11 的编译器上可用。
3. 流
#include <string>
#include <sstream>
int i;
float f;
double d;
std::string str;
// string -> integer
std::istringstream ( str ) >> i;
// string -> float
std::istringstream ( str ) >> f;
// string -> double
std::istringstream ( str ) >> d;
// error management ??
但是,使用此解决方案很难区分不良输入(请参阅此处(。
4. 提升lexical_cast
#include <boost/lexical_cast.hpp>
#include <string>
std::string str;
try {
int i = boost::lexical_cast<int>( str.c_str());
float f = boost::lexical_cast<int>( str.c_str());
double d = boost::lexical_cast<int>( str.c_str());
} catch( boost::bad_lexical_cast const& ) {
// Error management
}
但是,这只是sstream
的包装器,文档建议使用sstream
进行更好的错误管理(请参阅此处(。
5. 斯特托((*
由于错误管理,此解决方案很长,此处对此进行了介绍。由于没有函数返回纯 int,因此在整数的情况下需要进行转换(有关如何实现此转换的信息,请参阅此处(。
6. Qt
#include <QString>
#include <string>
bool ok;
std::string;
int i = QString::fromStdString(str).toInt(&ok);
if (!ok)
// Error management
float f = QString::fromStdString(str).toFloat(&ok);
if (!ok)
// Error management
double d = QString::fromStdString(str).toDouble(&ok);
if (!ok)
// Error management
结论
总而言之,最好的解决方案是C++11 std::stoi()
或者作为第二种选择,使用Qt库。所有其他解决方案都不鼓励或有缺陷。
std::istringstream ss(thestring);
ss >> thevalue;
为了完全正确,您需要检查错误标志。
使用 atoi
函数将字符串转换为整数:
string a = "25";
int b = atoi(a.c_str());
为了更详尽(并且正如评论中要求的那样(,我使用 std::from_chars
添加了 C++17 给出的解决方案。
std::string str = "10";
int number;
std::from_chars(str.data(), str.data()+str.size(), number);
如果要检查转换是否成功:
std::string str = "10";
int number;
auto [ptr, ec] = std::from_chars(str.data(), str.data()+str.size(), number);
assert(ec == std::errc{});
// ptr points to chars after read number
此外,要比较所有这些解决方案的性能,请参阅此快速工作台链接。 std::from_chars
是最快的,std::istringstream
是最慢的。
1. std::stoi()
std::string str = "10";
int number = std::stoi(str);
2. 字符串流
std::string str = "10";
int number;
std::istringstream(str) >> number;
3. boost::lexical_cast
#include <boost/lexical_cast.hpp>
std::string str = "10";
int number;
try
{
number = boost::lexical_cast<int>(str);
std::cout << number << std::endl;
}
catch (boost::bad_lexical_cast const &e) // Bad input
{
std::cout << "error" << std::endl;
}
4. std::atoi()
std::string str = "10";
int number = std::atoi(str.c_str());
5. sscanf()
std::string str = "10";
int number;
if (sscanf(str .c_str(), "%d", &number) == 1)
{
std::cout << number << 'n';
}
else
{
std::cout << "Bad Input";
}
Boost.Lexical_cast呢?
这是他们的例子:
下面的示例将命令行参数视为一系列数值数据:
int main(int argc, char * argv[])
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
std::vector<short> args;
while(*++argv)
{
try
{
args.push_back(lexical_cast<short>(*argv));
}
catch(bad_lexical_cast &)
{
args.push_back(0);
}
}
...
}
诚然,我的解决方案不适用于负整数,但它会从包含整数的输入文本中提取所有正整数。它利用numeric_only
区域设置:
int main() {
int num;
std::cin.imbue(std::locale(std::locale(), new numeric_only()));
while ( std::cin >> num)
std::cout << num << std::endl;
return 0;
}
输入文本:
the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878
输出整数:
5
25
7987
78
9878
类numeric_only
定义为:
struct numeric_only: std::ctype<char>
{
numeric_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
std::fill(&rc['0'], &rc[':'], std::ctype_base::digit);
return &rc[0];
}
};
完整的在线演示 : http://ideone.com/dRWSj
在 C++11 中,我们可以使用 "stoi"> 函数将字符串转换为 int
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1 = "16";
string s2 = "9.49";
string s3 = "1226";
int num1 = stoi(s1);
int num2 = stoi(s2);
int num3 = stoi(s3);
cout << "stoi("" << s1 << "") is " << num1 << 'n';
cout << "stoi("" << s2 << "") is " << num2 << 'n';
cout << "stoi("" << s3 << "") is " << num3 << 'n';
return 0;
}
这可能有点矫枉过正,但是 boost::lexical_cast<int>( theString )
应该做的工作相当不错。
嗯,很多答案,很多可能性。我在这里缺少的是一些通用方法,该方法将字符串转换为不同的C++整数类型(短整型、整型、长整型、布尔值等(。我想出了以下解决方案:
#include<sstream>
#include<exception>
#include<string>
#include<type_traits>
using namespace std;
template<typename T>
T toIntegralType(const string &str) {
static_assert(is_integral<T>::value, "Integral type required.");
T ret;
stringstream ss(str);
ss >> ret;
if ( to_string(ret) != str)
throw invalid_argument("Can't convert " + str);
return ret;
}
以下是用法示例:
string str = "123";
int x = toIntegralType<int>(str); // x = 123
str = "123a";
x = toIntegralType<int>(str); // throws exception, because "123a" is not int
str = "1";
bool y = toIntegralType<bool>(str); // y is true
str = "0";
y = toIntegralType<bool>(str); // y is false
str = "00";
y = toIntegralType<bool>(str); // throws exception
为什么不直接使用字符串流输出运算符将字符串转换为整数类型?答案如下:假设字符串包含的值超过了预期整数类型的限制。对于考试,在 Wndows 64 上,最大 int 是 2147483647。让我们给字符串赋一个值 max int + 1:string str = "2147483648"。现在,当将字符串转换为 int 时:
stringstream ss(str);
int x;
ss >> x;
x 变得2147483647,这绝对是一个错误:字符串"2147483648"不应该转换为 int 2147483647。提供的函数 toIntegralType 会发现此类错误并引发异常。
在Windows中,您可以使用:
const std::wstring hex = L"0x13";
const std::wstring dec = L"19";
int ret;
if (StrToIntEx(hex.c_str(), STIF_SUPPORT_HEX, &ret)) {
std::cout << ret << "n";
}
if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX, &ret)) {
std::cout << ret << "n";
}
strtol
,如果需要解释十六进制,stringstream
需要指定基数。
这个问题真的很老,但我认为有更好的方法
#include <string>
#include <sstream>
bool string_to_int(std::string value, int * result) {
std::stringstream stream1, stream2;
std::string stringednumber;
int tempnumber;
stream1 << value;
stream1 >> tempnumber;
stream2 << tempnumber;
stream2 >> stringednumber;
if (!value.compare(stringednumber)) {
*result = tempnumber;
return true;
}
else return false;
}
如果我写的代码正确,这将返回一个布尔值,告诉您字符串是否是有效数字,如果为 false,则不是数字,如果为 true,则为数字,该数字现在是结果,您将以这种方式调用它:
std::string input;
std::cin >> input;
bool worked = string_to_int(input, &result);
std::stringstream
,下面是一个示例:
#include <iostream>
#include <sstream>
using namespace std;
string r;
int main() {
cin >> r;
stringstream tmp(r);
int s;
tmp >> s;
cout << s;
return 0;
}
我的代码:
#include <iostream>
using namespace std;
int main()
{
string s="32"; //String
int n=stoi(s); //Convert to int
cout << n + 1 << endl;
return 0;
}
要从字符串表示转换为整数值,我们可以使用 std::stringstream。
如果转换的值超出整数数据类型的范围,则返回 INT_MIN 或 INT_MAX。
此外,如果字符串值无法表示为有效的 int 数据类型,则返回 0。
#include
#include
#include
int main() {
std::string x = "50";
int y;
std::istringstream(x) >> y;
std::cout << y << 'n';
return 0;
}
输出:50
根据上面的输出,我们可以看到它从字符串数转换为整数。
源代码和更多内容在字符串到整数 c++
错误处理未完成
int myatoti(string ip)
{
int ret = 0;
int sign = 1;
if (ip[0] == '-')
{
ip.erase(0, 1);
sign = -1;
}
int p = 0;
for (auto it = ip.rbegin(); it != ip.rend(); it++)
{
int val = *it - 48;
int hun = 1;
for (int k = 0; k < p; k++)
{
hun *= 10;
}
ret += val * hun;
p++;
}
return ret * sign;
}
来自 std::stoi()
:
// stoi example
#include <iostream> // std::cout
#include <string> // std::string, std::stoi
int main ()
{
std::string str_dec = "2001, A Space Odyssey";
std::string str_hex = "40c3";
std::string str_bin = "-10010110001";
std::string str_auto = "0x7f";
std::string::size_type sz; // Alias of size_t
int i_dec = std::stoi (str_dec,&sz);
int i_hex = std::stoi (str_hex,nullptr,16);
int i_bin = std::stoi (str_bin,nullptr,2);
int i_auto = std::stoi (str_auto,nullptr,0);
std::cout << str_dec << ": " << i_dec << " and [" << str_dec.substr(sz) << "]n";
std::cout << str_hex << ": " << i_hex << 'n';
std::cout << str_bin << ": " << i_bin << 'n';
std::cout << str_auto << ": " << i_auto << 'n';
return 0;
}
输出:
2001, A Space Odyssey: 2001 and [, A Space Odyssey]
40c3: 16579
-10010110001: -1201
0x7f: 127
long long toll(string a) {
long long ret = 0;
bool minus = false;
for (auto i : a) {
if (i == '-') {
minus = true;
continue;
}
ret *= 10;
ret += i-'0';
}
if (minus)
ret *= -1;
return ret;
}
用法:
long long a = toll(string("-1234"));
int stringToInt(std::string value) {
if (value.length() == 0 || value.find(std::string("NULL")) != std::string::npos || value.find(std::string("null")) != std::string::npos) {
return 0;
}
int i;
std::stringstream stream1;
stream1.clear();
stream1.str(value);
stream1 >> i;
return i;
}
> atoi
是一个内置函数,它将字符串转换为整数,假设字符串以整数表示形式开头。
另一种简单的方法:假设你有一个像c='4'
这样的字符,因此你可以执行以下步骤之一:
第一名:国际
Q q=(int) c ; (q is now 52 in ascii table ) .
q=q-48; remember that adding 48 to digits is their ascii code .
第二种方式:
q=c-'0'; the same , character '0' means 48
单行版本:long n = strtol(s.c_str(), NULL, base);
.
(s
是字符串,base
是int
,例如 2、8、10、16。
您可以参考此链接以获取strtol
的更多详细信息。
核心思想是使用strtol
功能,该功能包含在 cstdlib
中。
由于strtol
只处理char
数组,我们需要将string
转换为char
数组。您可以参考此链接。
举个例子:
#include <iostream>
#include <string> // string type
#include <bitset> // bitset type used in the output
int main(){
s = "1111000001011010";
long t = strtol(s.c_str(), NULL, 2); // 2 is the base which parse the string
cout << s << endl;
cout << t << endl;
cout << hex << t << endl;
cout << bitset<16> (t) << endl;
return 0;
}
这将输出:
1111000001011010
61530
f05a
1111000001011010
我认为从int
转换为std::string
反之亦然需要一些特殊功能,例如std::stoi()
但是,如果您需要将double
转换为string
请使用to_string()
(而不是 C#。C# 是 。ToString(( 不是 to_string(((<</p>
如果你有硬代码:)
bool strCanBeInt(std::string string){
for (char n : string) {
if (n != '0' && n != '1' && n != '2' && n != '3' && n != '4' && n != '5'
&& n != '6' && n != '7' && n != '8' && n != '9') {
return false;
}
}
return true;
}
int strToInt(std::string string) {
int integer = 0;
int numInt;
for (char n : string) {
if(n == '0') numInt = 0;
if(n == '1') numInt = 1;
if(n == '2') numInt = 2;
if(n == '3') numInt = 3;
if(n == '4') numInt = 4;
if(n == '5') numInt = 5;
if(n == '6') numInt = 6;
if(n == '7') numInt = 7;
if(n == '8') numInt = 8;
if(n == '9') numInt = 9;
if (integer){
integer *= 10;
}
integer += numInt;
}
return integer;
}
- 努力将整数转换为链表。不知道我在这里做错了什么
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 如何在C++中将整数转换为其数字数组
- 尝试将字符串/字符转换为整数会产生意外结果
- 如何使用C++将字符串中的字符转换为整数变量
- 如何将整数字符串转换为整数的二维向量?
- 如果整数与指针大小相同,则重新解释将整数转换为指针双射是否具有双射作用?
- 使用 "stringstream " 将字符串转换为整数
- 将字符串转换为浮点数或整数,而无需使用内置函数(如 atoi 或 atof)
- 如何检测 std::vector::emplace_back 上的隐式转换损失整数精度
- 如何防止双精度值到整数的隐式转换
- 为什么此指针值不能转换为整数的规则是什么?
- 如何解决隐式转换丢失整数精度:'size_t'(又名"无符号长")到'int'警告?
- 在 C++ 中将整数数组转换为位集表示形式的最佳方法?
- 为什么在将 void 指针转换为整数指针时出现分段错误
- 将字符串(可以是十进制字符串或十六进制字符串)转换为整数C++
- 整数类型应该显式转换(例如"int"到"无符号")还是只会增加混乱?
- 如何使用 STL 算法将整数向量转换为字符串向量?
- 无法将"整数 (*)[m]"转换为"整数 (*)[100000]
- 静态强制转换允许转换对象指针,但不允许转换整数