【发布时间】:2014-05-19 20:55:58
【问题描述】:
也就是说,基于ASCII表,从'0'到'9'的范围,
如何将它们转换为 0 到 9 的整数?
解决方案如:
char a = '6';
int b = a-48;
已经在这些部分周围浮动,但我想知道是否有其他方法可以在不使用幻数的情况下解决这个问题?
【问题讨论】:
-
使用
strtol怎么样?
也就是说,基于ASCII表,从'0'到'9'的范围,
如何将它们转换为 0 到 9 的整数?
解决方案如:
char a = '6';
int b = a-48;
已经在这些部分周围浮动,但我想知道是否有其他方法可以在不使用幻数的情况下解决这个问题?
【问题讨论】:
strtol怎么样?
由于'0'不保证是48,但保证数字是连续的,所以可以使用a-'0'。
【讨论】:
switch 声明或std::stringstream 为您进行转换。
'0'明确表达了意图,我不会称它为幻数。
如果你真的想要,你可以像这样使用stringstream:
#include <string>
#include <sstream>
int charToInt(char c) {
// initialize a buffered stream with a 1-character string
std::stringstream ss(std::string(1,c));
// read an int from the stream
int v;
ss >> v;
return v;
}
不是进行转换的最简单方法,但这样您就看不到任何涉及“魔术”数字或字符的实现细节。如果字符不是数字,您还会获得错误处理(引发异常)。
另一方面,如果您绝对确定字符 c 在 '0'..'9' 范围内,我不明白为什么不使用 c - '0'。
另一种解决方案是将c - 48 替换为c & 0xf,但这仍然涉及幻数并且比c - '0' 可读性差
【讨论】:
'0' 开始不是连续的,那么它不是 C++。这是对执行字符集的要求。
'0' 可能被解释为 ascii 48 而不是目标代码点。
0之后的每个字符的值应比前一个值大一”。由于源字符集和执行字符集[lex.phases]的不同,交叉编译时没有问题,“每个源字符集成员......都转换为执行字符集的成员”。所以'0' always 表示执行集中数字0 的值。当然,如果源代码被错误地解释为错误的编码,您就会遇到问题。
ascii 表以十六进制方式排序,因此很容易将数字字符更改为实数值,或者将大写字母更改为小写字母...
由于数字从 0x30 开始,然后是 0x30 =0 、0x31 = 1、0x32 =2 等,您必须删除 0x30 才能获得实际值。
char number='2';
int numberValue = (int)number - 0x30; /* you can rest the '0' value too */
同样,将 int 转换为 char 也是一样的,只需添加 0x30 即可。
int numberValue=5;
char number = (int)numberValue +0x30; /* or add '0' to your var */
【讨论】:
0。这在不同的字符集之间更便携。
从数字中减去 ASCII 零:
char a = '2';
int b = a-'0';
如果你不能使用'0',那这种作弊呢?
(int)(a + 2) % 10;
【讨论】:
如果它是一个字符,而不是一个字符指针,你可以这样做:
int convert (char x)
{
return (int(x) - int('0'));
}
【讨论】: