如何将字符数转换为十进制并返回或将ASCII’A’ – ‘Z’/’a’ – ‘z’转换为字母偏移0表示’A’/’a’…?

如果您的char在“0”到“9”范围内,如何将其转换为0到9的int值

然后你如何将它转换回来?

同时给出字母’A’到’Z’或’a’到’z’如何将它们转换为0-25然后再返回?

可以优化ASCII

C ++指定的基本字符编码使得转换为’0′ – ‘9’变得容易。

C ++指定:

在源和执行基本字符集中,上述十进制数字列表中0之后的每个字符的值应比前一个值大1。

这意味着,无论“0”的整数值,“1”的整数值是'0' + 1 ,“2”的整数值是'0' + 2 ,依此类推。 使用此信息和算术的基本规则,您可以轻松地从char转换为int并返回:

 char c = ...; // some value in the range '0' - '9' int int_value = c - '0'; // int_value is in the range 0 - 9 char c2 = '0' + int_value; 

将字母’a’或’z’可移植地转换为0到25之间的数字并不容易,因为C ++没有指定这些字母的值是连续的。 在ASCII中它们是连续的,你可以编写依赖于类似于上述代码’0′ – ‘9’的代码。 (这些天ASCII几乎无处不在)。

对于每个字符,可移植代码将使用查找表或特定检查:

 char int_to_char[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; int char_to_int[CHAR_MAX + 1] = {}; for (int i=0; i 

在C99中,您可以直接初始化char_to_int[]数据而无需循环。

 int char_to_int[] = {['a'] = 0, ['b'] = 1, ['c'] = 2, ['d'] = 3, ['e'] = 4, ['f'] = 5, ['g'] = 6, ['h'] = 7, ['i'] = 8, ['j'] = 9, ['k'] = 10, ['l'] = 11, ['m'] = 12, ['n'] = 13, ['o'] = 14, ['p'] = 15, ['q'] = 16, ['r'] = 17, ['s'] = 18, ['t'] = 19, ['u'] = 20, ['v'] = 21, ['w'] = 22, ['x'] = 23, ['y'] = 24, ['z'] = 25}; 

同样支持C99的C ++编译器也可以在C ++中作为扩展支持它。


这是一个完整的程序,可生成在这些转换中使用的随机值。 它使用C ++,加上C99指定的初始化扩展。

 #include  int digit_char_to_int(char c) { assert('0' <= c && c <= '9'); return c - '0'; } char int_to_digit_char(int i) { assert(0 <= i && i <= 9); return '0' + i; } int alpha_char_to_int(char c) { static constexpr int char_to_int[] = {['a'] = 0, ['b'] = 1, ['c'] = 2, ['d'] = 3, ['e'] = 4, ['f'] = 5, ['g'] = 6, ['h'] = 7, ['i'] = 8, ['j'] = 9, ['k'] = 10, ['l'] = 11, ['m'] = 12, ['n'] = 13, ['o'] = 14, ['p'] = 15, ['q'] = 16, ['r'] = 17, ['s'] = 18, ['t'] = 19, ['u'] = 20, ['v'] = 21, ['w'] = 22, ['x'] = 23, ['y'] = 24, ['z'] = 25}; assert(0 <= c && c <= sizeof(char_to_int)/sizeof(*char_to_int)); int i = char_to_int[c]; assert(i != 0 || c == 'a'); return i; } char int_to_alpha_char(int i) { static constexpr char int_to_char[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; assert(0 <= i && i <= 25); return int_to_char[i]; } #include  #include  int main() { std::random_device r; std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; std::mt19937 m(seed); std::uniform_int_distribution digits{0, 9}; std::uniform_int_distribution letters{0, 25}; for (int i=0; i<20; ++i) { int a = digits(m); char b = int_to_digit_char(a); int c = digit_char_to_int(b); std::cout << a << " -> '" << b << "' -> " << c << '\n'; } for (int i=0; i<20; ++i) { int a = letters(m); char b = int_to_alpha_char(a); int c = alpha_char_to_int(b); std::cout << a << " -> '" << b << "' -> " << c << '\n'; } } 

进行此转换有两种主要方式: 查找数学

在此答案中,所有ASCII值都以十进制概念表示

请注意,在ASCII中: '0' is 48'A' is 65'a' is 97

抬头:

在查找版本中,您有一个char数组,然后将映射的值放在数组中,并创建一个int数组以进行转换:

为了在将char映射到int时validation并获取相应的值:

 0 will be a sentinal value to mean not mapped: out of range all results will be one more than expected 

unsigned char用于确保正确处理带符号的否定字符

虽然’C’允许符号{[‘A’] = 1,[‘B’] = 2,…}; ,C ++没有,所以通常可以使用以下代码来填充查找表:

 void fill_lookups(unsigned char * from_table, int from_size, int * to_table) { for (int i = 0; i < from_size; ++i) { to_table[from_table[i]]=i+1; // add one to support 0 as "out of range" } } unsigned char int_to_char[]={ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; unsigned char int_to_lower[]={'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; unsigned char int_to_upper[]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; int char_to_int[UCHAR_MAX+2] = {}; // This will return 0 for non digits int letter_to_offset[UCHAR_MAX+2] = {}; // This will return 0 for non alpha fill_lookups(int_to_char, sizeof(int_to_char), char_to_int); fill_lookups(int_to_lower, sizeof(int_to_lower), letter_to_offset); fill_lookups(int_to_upper, sizeof(int_to_upper), letter_to_offset); // Helper function to check in range and always reduce in range lookups by 1 int to_int(int * table, unsigned char c, bool * in_range) { int ret = table[c]; if (ret) { *in_range=(1==1); // for C/C++ true --ret; } else { *in_range=(0==1); // for C/C++ false } return ret; } bool in_range; // always true in these cases int a=to_int(char_to_int, '7', &in_range); // a is now 7 char b=int_to_char[7]; // b is now '7' int c=to_int(letter_to_offset, 'C', &in_range); // c=2 int d=to_int(letter_to_offset, 'c', &in_range); // d=2 char e=int_to_upper[2]; // e='C' char f=int_to_lower[2]; // f='c' 

虽然这会起作用,如果需要validation或其他查找,这可能有意义,但......

一般来说,更好的方法是使用数学方程

以数学方式 (alpha适用于ASCII)

假设转换已经被validation在正确的范围内: (C样式转换用于C或C ++)

注意,'0' - '9'被保证在C和C ++中是连续的

对于ASCII'AZ'和'az'不仅是连续的,而且'A' % 32'a' % 32都是1

 int a='7'-'0'; // a is now 7 in ASCII: 55-48=7 char b=(char)7+'0'; // b is now '7' in ASCII: 7 + 48 int c='C' % 32 - 1; // c is now 2 in ASCII : 67 % 32 = 3 - 1 = 2 

- 或者 - 我们知道它是大写的

 int c='C'-'A'; // c is now 2 in ASCII : 67 - 65 = 2 int d='c' % 32 - 1; // d is now 2 in ASCII : 99 % 32 = 3 - 1 = 2 

- 或者 - 我们知道它是小写的

 int d='c'-'a'; // d is now 2 in ASCII : 99 - 97 = 2 char e=(char)2 + 'A'; // e is 'C' in ASCII : 65 + 2 = 67 char f=(char)2 + 'a'; // f is 'c' in ASCII : 97 + 2 = 99 

如果您知道字符c是字母或数字,您可以这样做:

 int cton( char c ) { if( 'a' <= c ) return c-'a'; if( 'A' <= c ) return c-'A'; return c-'0'; } 

添加需要的任何错误检查c

要将整数n转换回char ,只需要'0'+n如果你想要一个数字, 'A'+n如果你想要一个大写字母, 'a'+n如果你想要小写。

注意:这适用于ASCII(因为OP已标记。)但请参阅Pete的内容。

如果我理解正确,你想这样做:

 #include  /* for toupper */ int digit_from_char(char c) { return c - '0'; } char char_from_digit(int d) { return d + '0'; } int letter_from_char(char c) { return toupper(c) - 'A'; } char char_from_letter(int l) { return l + 'A'; }