新聞速報

        

2014年3月3日 星期一

C語言 送出一個中文字 ( 字元陣列)

輸出至 RS-232 時的注意事項:
   必須是 ASCII Code ,一個中文字 為 2 個 Bytes   
 
   資料若是以 Byte 組合出來時:
 
   "我"  Big5  編碼為 A7 DA

   char buffer_3[] ={ 0xA7 , 0xDa };  
   printf( "buffer_3[]=%s , sizeof=%d , strlen=%d \n" , buffer_3 , sizeof(buffer_3) , strlen(buffer_3));
 
--> buffer_3=我 , sizeof=2 , strlen=2 

有可能得到結果為 buffer_3= "我@!@#$%^&*(&&*%^" ,strlen= ??,因為 strlen( )會把其陣列轉為字串處理,會一直去找結束字元 \0。當陣列內容沒有明確放入 \0,可能會找到其他記憶體空間 
 如果送出的資料以位元組為主,就搭配 sizeof( )
   write( fd , buffer_3 , sizeof(buffer_3) );
  "琝" Big5 編碼為 DA A7

   char buffer_4[] ={ 0xDA , 0xA7 , 0x00 };  

   printf( "buffer_4[]=%s , sizeof=%d , strlen=%d \n" , buffer_4 , sizeof(buffer_4) , strlen(buffer_4));  
 
--> buffer_4=琝 , sizeof=3 , strlen=2  

如果送出的資料以字串(有加上 \0 結束字元)為主,可搭配 strlen( )
   write( fd , buffer_4 , strlen(buffer_4) ); 

 下列情況要注意:
   若是程式碼直接以字串變數輸出中文字時,送出至RS-232會以 Unicode字元輸出
 
   "直" Big5 編碼為 AA BD , Unicode編碼為 E7 9B B4
   char buffer_2[100] = "直";  
   printf( "buffer_2[100]=%s , sizeof=%d , strlen=%d \n" , buffer_2 , sizeof(buffer_2) , strlen(buffer_2));  
 
 --> buffer_2[100]=??, sizeof=100 , strlen=3  (有 3 個BYTES)
 --> buffer_2[0] = 0xE7 buffer_2[1] = 0x9B buffer_2[2] = 0xB4
 
   write( fd , buffer_2 , strlen(buffer_2) );



   在客顯看到亂碼,因為該字被轉成 Unicode 字元送出

必須使用 iconv_open()、iconv()、iconv_close() 將UTF-8 轉為 BIG5
 
在 Linux PC下,可以正常使用這三個函式。
但是在 Embedded Linux下,使用 iconv_open("BIG5", "UTF8"); 會失敗。
經過測試後,發現只有iconv_open("UTF8", "UTF8"); 可以成功使用。
似乎Embedded Linux的環境不支援其他編碼、或 Embedded Linux的LIB被簡化過(iconv_open()只剩下 UTF8...)。
 
   PS:網路上找的資料是要額外掛載 libiconv 函式庫

 UTF-8 轉 BIG5 有兩種使用方法:
iconv_open("BIG5", "UTF8");
iconv_open("CP950", "UTF8");  //有些擴充字可以順利轉換出來

沒有留言:

張貼留言