强制字符串为int函数以消耗整个字符串
Forcing String to int Function to Consume Entire String
给定一个字符串,它应该表示一个数字,我想把它放入一个转换函数,如果整个字符串没有转换,将提供通知。
输入:"12"
:
-
istringstream::operator>>
输出12 -
atoi
输出12 -
stoi
输出12
对于输入"1X"
,我想要一个失败响应,但我得到:
-
istringstream::operator>>
输出1
atoi
输出1stoi
输出1输入"X2"
:
-
istringstream::operator>>
输出0并设置错误标志 -
atoi
输出0
stoi
抛出错误是否有一种方法可以引起输入"1X"
的错误行为?
Edit:在c++17或更高版本中优先使用from_chars
。更多信息请看这里:https://topanswers.xyz/cplusplus?q=724#a839
对于给定的string str
,有几种方法可以实现这一点,每种方法都有优点和缺点。我在这里写了一个实例:https://ideone.com/LO2Qnq,并在下面讨论:
strtol
如这里所建议的,strtol
的out参数可用于获取读取的字符数。strtol
实际上返回的是long
而不是int
,所以在返回时发生了强制转换。
char* size;
const int num = strtol(str.c_str(), &size, 10);
if(distance(str.c_str(), const_cast<const char*>(size)) == str.size()) {
cout << "strtol: " << num << endl;
} else {
cout << "strtol: errorn";
}
注意,这里使用str.c_str()
来引用同一个字符串。c_str
返回作为字符存储的底层数组的指针,如果您使用c++ 11:
c_str()
和data()
执行相同的功能
还请注意,c_str
返回的指针在strtol
和distance
调用之间将有效,除非:
- 将
string
的非const
引用传递给任何标准库函数- 在
string
上调用非const
成员函数,不包括operator[]
、at()
、front()
、back()
、begin()
、rbegin()
、end()
和rend()
如果您违反了上述任何一种情况,您将需要创建i
的底层const char*
的临时副本并在其上执行测试。
sscanf
sscanf
可以使用%zn
返回读取的字符数,这可能比做指针比较更直观。如果基础很重要,sscanf
可能不是一个好的选择。与strtol
和stoi
不同,sscanf
只提供八进制(%o
)、十进制(%d
)和十六进制(%x
)的说明符。
size_t size;
int num;
if(sscanf(str.c_str(), "%d%zn", &num, &size) == 1 && size == str.size()) {
cout << "sscanf: " << num << endl;
} else {
cout << "sscanf: errorn";
}
stoi
正如这里所建议的,stoi
的输出参数的工作方式类似于sscanf
的%n
,返回读取的字符数。与c++保持一致,这需要一个string
,与上面的C实现不同,stoi
抛出invalid_argument
,如果第一个非空格字符不是当前基数的数字,这不幸意味着与C实现不同,它必须在try
和catch
块中检查错误。
try {
size_t size;
const auto num = stoi(str, &size);
if(size == str.size()) {
cout << "stoi: " << num << endl;
} else {
throw invalid_argument("invalid stoi argument");
}
} catch(const invalid_argument& /*e*/) {
cout << "stoi: errorn";
}
您也可以使用前面提到的std::istringstream
,但是要确保它被解析到流的末尾。假设您有一个常量引用,您可以执行如下操作
T parse(const std::string& input) {
std::istringstream iss(input);
T result;
iss >> result;
if (iss.eof() || iss.tellg() == int(input.size())) {
return result;
} else {
throw std::invalid_argument("Couldn't parse entire string");
}
}
这种方法的好处是您可以解析任何重载operator>>
的内容。注:我不完全确定这个条件是否足够,但根据我的测试,它似乎是足够的。由于某些原因,如果解析到末尾,流将得到一个失败标记。
- 字符串函数在目标C++上运行时C++返回空
- 字符串函数返回奇怪的值
- 这里的字符串函数是什么意思
- 在字符串函数中抛出'char const*'实例后调用的终止
- 为什么 stl 字符串C++函数有时出错有时会出错?
- 从C++为字符串函数设置_ENV
- 来自 2D 数组的字符串函数
- 返回最长的公共子字符串函数 c ++
- 使用getline和字符串函数C++程序中的分段错误
- 在字符串函数的指针中返回地址
- 字符串函数:strcat()
- 这个子字符串函数有什么问题
- 字符串函数不返回字符串? C++
- 使用向量和字符串函数返回字符串
- 尝试修复一个字符串函数,该函数采用字符串并通过替换一些单词来更改它
- 逐字读取字符数组,无需字符串函数
- 我从我的字符串函数返回到主函数
- 为什么我不能从字符串函数返回字符串数组?
- 如何在不使用字符串函数的情况下在char数组中找到字符串?(C )
- 带有 #include< iostream.h> 的程序允许使用 strlen() 等字符串函数。为什么?