我想将一个字符串转换为整数,而不是ASCII码。
简单来说,我们会得到一个字符串方程。我们需要将其分解,正确格式化并解决线性方程。但是,我无法将字符串转换为整数。
我知道这个字符串的格式将是(-5)或(25)等,因此它一定是整数。但是如何从一个字符串中提取出它呢?
我考虑的一个方法是通过字符串运行for / while循环,检查数字,提取其后的所有数字,然后查看是否有前导'-',如果有,则将整数乘以-1。
但对于这样一个小问题来说,似乎有点过于复杂了。你们有什么好主意吗?
方法 | 错误处理 | 优点和缺点 |
---|---|---|
std::from_chars c++17 |
std::from_chars_result (手动错误处理) |
✔️ 快速且零开销 ✔️ 支持任意基数作为运行时参数 ✔️ 也适用于浮点数,可选择格式 ❌ 接口不人性化 ❌ 不支持区域设置 |
std::sto*系列 c++11 |
std::invalid_argument std::out_of_range (异常) |
✔️ 简单接口 ✔️ 支持任意基数作为运行时参数 ✔️ 也适用于浮点数 ✔️ 在正常情况下没有额外开销 ❌ 如果错误频繁发生效率低下 ❌ 名称晦涩 ❌ 不支持区域设置 |
std::istringstream c++98 |
bool 标志,或stream.exceptions() |
✔️ 通用方法(适用于具有>> 运算符的类型)✔️ 考虑区域设置(例如,可以更改基数) ✔️ 可以检测不同的格式(例如, 0x... )❌ 慢且流的开销很大 ❌ 对不同基数的支持有限 |
std::strto*系列 c++98 |
std::errno (全局标志,手动) |
✔️ 生成的汇编代码较小 ✔️ 在正常/异常情况下开销较小 ✔️ 支持任意基数作为运行时参数 ✔️ 与C兼容 ✔️ 也适用于浮点数 ✔️ 支持区域设置 ✔️ 如果基数为零,可以检测不同的格式 ❌ 名称晦涩 ❌ 接口不人性化 |
std::ato*系列 c++98 |
零表示失败 (手动错误处理) |
✔️ 生成的汇编代码较小 ✔️ 简单接口 ✔️ 在正常/异常情况下开销较小 ✔️ 与C兼容 ✔️ 也适用于浮点数 ❌ 名称晦涩 ❌ 对于 int ,不支持基数、格式等 |
std::sscanf c++98 |
int 解析的参数数量(手动错误处理) |
✔️ 生成的汇编代码较小 ✔️ 也适用于浮点数 ✔️ 可以检测不同的格式(例如, 0x... )✔️ 与C兼容 ❌ 接口不人性化 ❌ 没有类型安全性,容易出错 ❌ 对不同基数的支持有限 |
std::from_chars
,或者如果不可用,则使用std::strto*
。
std::sto*
或std::istringstream
中的异常开销是不可接受的。std::strto*
。std::istringstream
。std::sto*
,或者创建一个std::from_chars
的包装器。大多数特殊情况是不太可能发生的,所以大部分时间,请使用std::stoi
或std::from_chars
的包装器:
// could be generalized with a template
bool parse_int(std::string_view str, int& out, int base = 10) {
auto [ptr, err] = std::from_chars(str.data(), str.data() + str.size(), out, base);
return err == std::errc{};
}
std::string s = ...;
if (int x; parse_int(s, x)) {
// x has been parsed :)
}
// alternative pre-C++17 version
bool parse_int(const std::string& str, int& out, int base = 10) {
errno = 0;
char* end = nullptr;
out = std::strtol(str.data(), str.data() + str.size(), &end, base);
return str.data() != end && errno == 0;
}
parse_int
返回std::optional<int>
而不是分配一个引用。好的,有很多答案,很多可能性。我在这里缺少的是一些通用的方法,可以将字符串转换为不同的C++整数类型(short、int、long、bool等)。
我想出了以下解决方案:
#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输出运算符将字符串转换为整数类型呢? 答案如下: 假设一个字符串包含一个超过预期整数类型限制的值。例如,在Windows 64上,最大的int是2147483647。 让我们给一个字符串赋值为max int + 1:string str = "2147483648"。 现在,当将字符串转换为int时:
stringstream ss(str);
int x;
ss >> x;
x变成了2147483647,这明显是一个错误:字符串“2147483648”不应该被转换为整数2147483647。提供的函数toIntegralType可以检测此类错误并抛出异常。
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
需要指定进制以解释十六进制。
您可以使用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 <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;
}
std::string input;
std::cin >> input;
bool worked = string_to_int(input, &result);
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;
}
来自 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
我的代码:
#include <iostream>
using namespace std;
int main()
{
string s="32"; //String
int n=stoi(s); //Convert to int
cout << n + 1 << endl;
return 0;
}
atoi
是一个内置函数,它将字符串转换为整数,假设字符串以整数表示开头。
atoi
时,使用 strtol
替代。 - Ben Voigt要将字符串表示转换为整数值,我们可以使用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
根据上述输出,我们可以看到它从字符串数字转换为整数。
更多信息请参见{{link1:C++中的字符串转整数}}
atoi()
函数吗? - i_am_jorfint atoi (const char* str);
功能:将参数str
所指向的字符串转换为一个整数(类型为int
)。返回值:如果转换成功,则返回该整数,否则返回零。注意事项:int
类型的范围,则返回INT_MAX
或INT_MIN
,具体取决于转换结果的符号。/* atoi examples */ #include /* printf */
#include /* atoi */
int main ()
{
int i;
char buffer[256];
printf ("Enter a number: ");
fgets (buffer, 256, stdin);
i = atoi (buffer);
printf ("The value entered is %d. Its double is %d.\n",i,i*2);
return 0;
}
- i_am_jorfmyString
的std::string
,而想要使用atoi
函数,则需要输入atoi(myString.c_str())
。 - Robᵩ