C++ Atoi 无法处理特殊字符

Posted

技术标签:

【中文标题】C++ Atoi 无法处理特殊字符【英文标题】:C++ Atoi can't handle special characters 【发布时间】:2021-12-13 13:01:33 【问题描述】:

我正在使用这个 atoi 从字符串中删除所有字母。但是我的字符串使用了如下所示的特殊字符,因此我的 atoi 退出时出现错误。我该怎么做才能解决这个问题?

#include <iostream>
#include <string>
using namespace std;
 
int main() 
    std::string playerPickS = "Klöver 12"; // string with special characters
 
    size_t i = 0;
    for (; i < playerPickS.length(); i++)  if (isdigit(playerPickS[i])) break; 
 

    playerPickS = playerPickS.substr(i, playerPickS.length() - i); // convert the remaining text to an integer
 
    cout << atoi(playerPickS.c_str());
 

这是我认为的错误。我只有在使用那些特殊字符时才会得到这个,这就是为什么我认为这是我的问题。

【问题讨论】:

当你说你的“atoi exits with an error”是什么意思?什么“错误”?请edit您的问题向我们提供更多详细信息。也请花一些时间阅读the help pages,阅读SO tour,阅读How to Ask,以及this question checklist。 有什么办法可以去除字符串中的特殊字符? @AlexanderStröm 这是一个完全独立的问题。您的代码 sn-p 不完整。这是一个微不足道的案例,您应该能够轻松地生成 minimal reproducible example。 您的编译器使用什么编码来创建字符串文字,或者字符串中每个字节的值是什么?你打电话给setlocale了吗? Why shouldn't I use atoi()? (duplicate)。请改用strtol 【参考方案1】:

char 可以是有符号或无符号的,但没有区域设置重载的 isidigt 需要一个正数(或 EOF==-1)。在您的编码中 'ö' 有一个负值。您可以先将其转换为 unsigned charis_digit(static_cast&lt;unsigned char&gt;(playerPickS[i])) 或使用可识别区域设置的变体。

【讨论】:

【参考方案2】:

atoi 在发现不是数字的东西时停止扫描(粗略地说)。所以,要让它做你想做的事,你必须给它提供至少以你要转换的字符串开头的东西。

来自documentation:

[atoi] 丢弃任何空白字符,直到找到第一个非空白字符,然后采用尽可能多的字符来形成有效的整数表示并将它们转换为整数值。有效的整数值由以下部分组成:

(可选)加号或减号 数字

所以,现在您知道atoi 是如何工作的了,您可以在传入之前适当地预处理您的字符串。祝您好运!


编辑:如果您对isdigit 的调用未能产生预期的结果,则线索在于here:

如果 ch 的值不能表示为 unsigned char 且不等于 EOF,则行为未定义。

因此,您需要在调用之前自行检查。将playerPickS[i] 转换为unsigned int 可能会起作用。

【讨论】:

我认为isdigit 检查的目的是确保atoi 以数字开头。 @MSalters 啊,好的。我会更新我的答案。 @MSalters 好的,完成了。 @vll 好的,我明白你的意思了,谢谢。我已经更新了我的答案。

以上是关于C++ Atoi 无法处理特殊字符的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode - 8 - String to Integer (atoi)

linux变量里有特殊字符脚本会对其处理吗

url 中的特殊字符 % # & = ? / + 无法被后端解析问题分析及解决方法

Hibernate 和 Spring Data JPA 无法处理带有特殊字符的 Oracle 表名?

将字符串转换为 int (C++)

C++特殊字符转义序列