簡體   English   中英

您如何將字符數字轉換為十進制並返回或將 ASCII 'A'-'Z'/'a'-'z' 轉換為 'A'/'a' 的字母偏移量 0 ......?

[英]How do you convert char numbers to decimal and back or convert ASCII 'A'-'Z'/'a'-'z' to letter offsets 0 for 'A'/'a' ...?

如果您有一個在“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<sizeof(int_to_char); ++i) {
  char_to_int[int_to_char[i]] = i;
}

// convert a lowercase char letter to a number in the range 0 - 25:
int i = char_to_int['d'];

// convert an int in the range 0 - 25 to a char
char c = int_to_char[25];

在 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 <cassert>

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 <random>
#include <iostream>

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<int> digits{0, 9};
  std::uniform_int_distribution<int> 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時驗證並獲取相應的值:

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'

雖然這會起作用,並且如果需要驗證或其他查找,這可能是有道理的,但是......

一般來說,更好的方法是使用數學方程

數學上(alpha 適用於 ASCII)

假設轉換已經被驗證在正確的范圍內:(用於 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 <ctype.h>    /* 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';
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM