ASCII與中文

Ascii Code 1-31為控制碼

字元 Ascii code
\0 0
0-9 48-57
A-Z 65-90
a-z 97-122
空格 32

印出中文Ascii code

字元char的範圍為0-255,不包含負數,只有正整數。

中文的Ascii Code 128-255,數字、大小寫英文字母、空格、標點符號、空字元(\0)介於Ascii Code 0-127。

字元char是0-255,沒有負數,在把中文字元轉換成整數之前,必須先轉成unsigned char,再轉成int,才會正確顯示中文的ascii碼。

1
(int)(unsigned char)str[i] 
1
2
3
4
5
6
7
8
9
10
11
12
13
int main() {
  char str[100];
  //清空字串位址的值
  memset(str, 0, sizeof(str));
  strcpy(str, "西西");
  cout << "長度:" << strlen(str) << endl;
  for(int i = 0, len = strlen(str); i < len; i++) {
    cout << "str[" << i << "] = " <<  (int)(unsigned char)str[i] << endl;
  }
  //印出字串
  cout << str << endl;
  return 0;
}
長度:6
str[0]=232
str[1]=165
str[2]=191
str[3]=232
str[4]=165
str[5]=191
西西

使用中文Ascii Code指定陣列值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() {
  char str[100];
  //清空字串位址的值
  memset(str, 0, sizeof(str));
  str[0] = 232;
  str[1] = 165;
  str[2] = 191;
  str[3] = 232;
  str[4] = 165;
  str[5] = 191;
  //印出字串
  cout << str << endl;
  return 0;
}
西西

統計中文個數

寫一個程式,計算中文個數,一個中文字算1個,一個英文字算1個。

不同的編碼方式中文個數不同。

  • utf-8 中文3個byte,英文1個byte。
  • unicode 中文2個byte,英文2個byte。

數字、大小寫英文字母、空格、標點符號、空字元(\0)介於Ascii Code 0-127。

中文的Ascii Code 128-255。

從之前的程式碼範例,「西西」二個中文字,但卻產生6個char,C++ 1個char是1byte,「西西」二個字占6byte,一個中文字占3byte,代表目前我的編譯器是使用utf-8。

以下程式碼max_chinese_cnt = 3,代表一個中文字使用3個byte。

chinese_cnt計算byte數量,chinese_cnt = 1,由1開始,加到第3個byte代表一個中文字讀取完畢,可以count++。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int countChar(const char* str) {
  if(str == 0) return -1;
  int count = 0;  // 統計字數,一個中文字算1個,一個英文字算1個
  int chinese_cnt = 1;  // 由1開始
  int max_chinese_cnt = 3;  // 一個中文字使用3個byte
  for(int i = 0, len = strlen(str); i < len; i++) {
    // cout << "str[" << i << "] = " <<  (int)(unsigned char)str[i] << endl;
    unsigned int ch = (int)(unsigned char)str[i];
    if(ch < 128) {  // 英文字母走這邊
      count++;
    } else {  // 中文走這邊
      // 加到第3個byte代表一個中文字讀取完畢,可以count++
      if (chinese_cnt == max_chinese_cnt) {
        count++;
        chinese_cnt = 1;
      } else {
        // 尚未讀取完一個中文字
        chinese_cnt++;
      }
    }
  }
  return count;
}
int main() {
  cout << countChar("西西abc") << endl;
  return 0;
}  
5

以下是另外一種寫法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int countChar(const char* str) {
  if(str == 0) return -1;
  int count = 0;
  int chinese_cnt = 1;
  int max_chinese_cnt = 3;
  while(*str) {
    //0
    if((unsigned char) *str < 128) {
      count++;
    } else {
      if (chinese_cnt == max_chinese_cnt) {
        count++;
        chinese_cnt = 1;
      } else {
        chinese_cnt++;
      }
    }
    str++;
  }
  return count;
}
int main() {
  cout << countChar("西西abc") << endl;
  return 0;
}
5

2byte中文

以下程式碼適合編碼為2byte的中文,用一個flag判斷是否讀完2byte,若

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int countChar(const char* str) {
  if(str == 0) return -1;
  int count = 0;
  // flag預設值
  bool flag = false;
  while(*str) {
    //0
    if((unsigned char) *str < 128) {
      count++;
    } else {
      if(flag) {
        // 讀到中文第2個byte,把flag變false,代表讀完一個中文
        // 中文個數+1
        count++;
        flag = false;
      } else {
        // 讀到中文第1個byte,把flag變true
        flag = true;
      }
    }
    str++;
  }
  return count;
}
int main() {
  cout << countChar("西西abc") << endl;
  return 0;
}
5

Unicode與utf-8

Ascii Code只能支持英語美語,大小只有128,只有正整數沒有負數。

因為要支援其它國家的語言,才會有Unicode,Unicode包含Ascii,中文字佔2byte、英文字佔2byte,但英文字占太多記憶體大小。

utf-8,比Unicode更省記憶體大小,英文佔1byte,中文佔3byte。

results matching ""

    No results matching ""