如何将std::字符串转换为int?

我想将字符串转换为int,我不是指ASCII代码。

为了快速运行,我们将一个方程作为字符串传递。我们要分解它,正确格式化它并求解线性方程。现在,这么说,我无法将字符串转换为int。

我知道字符串的格式是(-5)或(25)等,所以它肯定是一个int。但是我们如何从字符串中提取它?

我想的一种方法是在字符串中运行for/这时候循环,检查一个数字,提取之后的所有数字,然后查看是否有前导'-',如果有,将int乘以-1。

这么小的问题,好像有点复杂了,大家有什么想法吗?

1965020 次浏览

使用atoi函数将字符串转换为整数:

string a = "25";


int b = atoi(a.c_str());

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

std::istringstream ss(thestring);
ss >> thevalue;

要完全正确,您需要检查错误标志。

atoi是一个内置函数,它将字符串转换为整数,假设字符串以整数表示开头。

诚然,我的解决方案不适用于负整数,但它会从包含整数的输入文本中提取所有正整数。它使用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

什么是加油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);
}
}
...
}

这可能有点过分,但是 boost::lexical_cast<int>( theString )应该对工作 还不错

在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

还有另一种简单的方法:假设您有一个像c='4'这样的字符,因此您可以执行以下步骤之一:

1:int q

q=(int)c;(q现在在ascii表中是52)。 q=q-48;记住,数字加48是他们的ascii代码。

第二种方式:

q=c-'0'; the same , character '0' means 48

可能的选择如下:

1. sscanf()

    #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显示),因为"没有字段宽度限制的scanf可能会在某些版本的libc上因输入大量数据而崩溃"(请参阅这里这里)。

2. std::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. sstream

    #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. Boost的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. strto()*

由于错误管理,此解决方案非常长,在此进行描述。由于没有函数返回纯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++11std::stoi(),或者作为第二个选择,使用Qt库。所有其他解决方案都不鼓励或有错误。

在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";
}

strtolstringstream如果需要解释十六进制需要指定基数。

嗯,有很多答案,很多可能性。这里我缺少的是一些通用方法,可以将字符串转换为不同的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

为什么不直接使用stringstream输出运算符将字符串转换为整型? 以下是答案: 假设一个字符串包含一个超过预期整数类型限制的值。例如,在Wndows 64 max int上是2147483647。 让我们为字符串分配一个值max int+1:string str="2147483648"。 现在,当将字符串转换为int时:

stringstream ss(str);
int x;
ss >> x;

x变为2147483647,这绝对是一个错误:字符串“2147483648”不应该转换为int 2147483647。提供的函数toAccalType发现此类错误并抛出异常。

单行版本:long n = strtol(s.c_str(), NULL, base);

s是字符串,baseint,例如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

来自http://www.cplusplus.com/reference/string/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年,太空奥德赛:2001年和[,太空奥德赛]

40c3:16579

-10010110001:-1201

0x7f: 127

我的代码:

#include <iostream>
using namespace std;


int main()
{
string s="32";  //String
int n=stoi(s);  //Convert to int
cout << n + 1 << endl;


return 0;
}
ll toll(string a){
ll 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;
# ll is defined as, #define ll long long int
# usage: ll a = toll(string("-1234"));
}

要将字符串表示转换为整数值,我们可以使用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

根据上面的输出,我们可以看到它从字符串数字转换为整数。

源和更多在string to intc++

1.圣d::

std::string str = "10";
int number = std::stoi(str);

2.字符串流

std::string str = "10";
int number;
std::istringstream(str) >> number

3.提升::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.圣d::a

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";
}

我知道这个问题很老,但我认为有更好的方法

#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);

为了更详尽(正如评论中要求的那样),我添加了C++17使用std::from_chars给出的解决方案。

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

此外,要比较所有这些解决方案的性能,请参阅以下快速工作台链接:https://quick-bench.com/q/GBzK53Gc-YSWpEA9XskSZLU963Y

std::from_chars最快,std::istringstream最慢)

如果你有硬代码:)

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;
}
 int stringToInt(std::string value) {
if(value.length() == 0 ) return 0; //tu zmiana..


if (value.find(  std::string("NULL") ) != std::string::npos) {
return 0;
}
 

if (value.find(  std::string("null") ) != std::string::npos) {
return 0;
}
 

 

int i;
std::stringstream stream1;
stream1.clear();
stream1.str(value);
stream1 >> i;
return i;

};

我认为从int转换到std::string或反之需要一些特殊功能,例如std::stoi() 但是,如果您需要将double转换为string,请使用to_string()(不是C#。C#是. ToString()不是to_string())

你可以使用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;
}

在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;
}