日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ANSI,ASCII,UNICODE

發布時間:2025/3/20 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ANSI,ASCII,UNICODE 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載:http://blog.csdn.net/zj510/article/details/38368397

一直以來,編碼問題都是比較令人糾結的,我自己也是,迷惑了好一段時間。

首先看一下ANSI編碼和ASCII 編碼,用google搜到這篇文章,挺好的。http://www.differencebetween.net/technology/web-applications/difference-between-ansi-and-ascii/

ASCII: American Standard Code for Information Interchange

ANSI: American National Standard Institute

基本的區別就是:

[plain] view plaincopyprint?
  • Summary:?
  • ?
  • ANSI has more characters than ASCII?
  • ASCII uses 7 bits while ANSI uses 8?
  • ASCII characters are fixed to the code points while ANSI code points may represent different characters?
  • ASCII is more straightforward to use than ANSI?
  • ASCII works with Unicode while ANSI compatibility is very limited?
  • Summary:ANSI has more characters than ASCII ASCII uses 7 bits while ANSI uses 8 ASCII characters are fixed to the code points while ANSI code points may represent different characters ASCII is more straightforward to use than ANSI ASCII works with Unicode while ANSI compatibility is very limited

    然后又看到這篇文章,也不錯,http://blog.csdn.net/zj510/article/details/37877651。建議仔細閱讀。

    這里,我主要再介紹一下ansi,unicode和utf8

    首先看一下ANSI

    ANSI編碼

    首先在C++代碼里面敲入一行代碼,很簡單看下圖,運行一下,會發現字符串ansi里面的內存是0xb3, 0xcc, 0xd0, 0xf2, 0xd4, 0xb1.打開記事本,寫入“程序員”3個字,然后save,用ultraedit看一下十六進制編碼,如下圖。

    跟VS里面看到的一模一樣。我們在看一下C++的源文件。

    看16進制的源文件,可以發現源文件里面的“程序員”3個字也是ANSI編碼。好像VS對于C++源文件默認的就是ANSI編碼,我在VS2013里面看到有個功能可以自動檢測UTF-8編碼啥的。但是沒有仔細研究過。

    OK, 現在我們知道,在notepad里面,打入一些字符,然后save,那么默認的就是ANSI編碼。在VS里面如果輸入一些常量字符串,假如是純英文的話,那應該也是ANSI編碼,如果你的常量字符串里面有中文或者韓文等其他字符的話,就視情況而定了,像vs2013可能會把你的源文件轉換成UTF8格式,但我知道早期的VS是不會轉的還是用ANSI.所以如果你在IDE,比如VS, Eclipse,甚至XCODE等里面輸入常量字符串的話,需要小心。通常如果只是英文的話,一般是沒有問題的,但是如果有中文的話,要留個心眼,看你的IDE是怎么編碼的。不然恐怕就會出現亂碼的情況。當然如果真的有中文等字符的話,也不建議使用ANSI編碼,盡可能使用UNICODE吧。

    UNICODE

    unicode其實有好幾種,比如unicode16,unicode32啥的。通常我們在寫程序的時候,說起unicode或者寬字符,一般指的就是unicode16.也就是2個字節(wchar_t)來表示一個字符。一個英文字母a使用2個字節的寬字節wchar_t來表示,一個中文也是用一個wchar_t來表示。

    notepad的saveas里面有個功能,可以把當前文件保存成unicode。

    同樣打開notepad輸入“程序員”3個字,然后點擊save as,在編碼那里選擇unicode。如圖

    保存完之后,用ultraedit打開,前面兩個字節FFFE,這個其實是notepad的一個標記,不用管它,看后面的6個字節。“程序員”總共是3個中文字符,那么用unicode就是6個字節,也就是0B7A8F5E5854.

    OK, 現在C++程序里面敲入一行代碼,如下圖.從下面的圖片里面可以看到unicode字符串的內存是0x7a0b, 0x5e8f, 0x5458.跟上面ultraedit里面比較。好像每兩個字節都反過來了,這是何故?

    其實這里有個很好玩的事情。我們直接看unicode里面的指向的內存吧。

    unicode指向的是地址0x0026fb90,看內存,內存里面的數據是0b, 7a, 8f, 5e, 58, 54。跟上面ultraedit里面顯示的是一致的。那么說明unicode里面在內存存放的字節流跟ultraedit里面展示的是一模一樣的。那為什么用wchar_t表示的時候就反過來了呢?其實我覺得這應該是windows上面的機制,用wchar_t表示的時候就是反過來的(不知道linux上是不是也是這樣?),就好象是int在內存里面存放也是逆序的。

    順便再來看一下C#吧,寫幾行簡單代碼,直接看下圖:

    首先我們可以看到sizeof(char)在C#里面是2.其實在C#里面并沒有wchar_t這種東西。只有一個char,而它就是2個字節。這是因為C#里面用的都是unicode。C#的string里面存放的就是unicode格式。好像Java也是這樣。每一個char和上面的C++的wchar_t的值一模一樣。


    ANSI VS Unicode

    那么我們到底應該使用ANSI還是Unicode呢?我建議使用Unicode,特殊是在寫windows程序的時候,因為windows的API都支持ANSI和Unicode兩種,也就是我們常說的多字節和寬字節。比如CreateFileA()支持ANSI編碼, CreateFileW()支持Unicode編碼。如果使用Ansi的話,萬一你的字符串里面含有中文,就會比較麻煩一些,比如有些時候為了換行,很難計算,以為ANSI里面英文占一個自己,中文占2個字節。如果把一個中文給劈開了,那就顯示亂碼了。如果使用Unicode就很方便了,因為中文,英文都是占2個字節。當然如果你的程序確定只支持英文,那用ANSI也行,畢竟用Unicode的話,會多占內存。假如一個英文字符串有100個字符,用ANSI就占用100字節,用UNICODE就是200字節。Windows的大多數API都支持ANSI和UNICODE兩種,我個人比較喜歡用UNICODE版本,畢竟現在的內存動不動都4g,8g的,多耗些內存也不是什么大問題。


    utf8

    最后再介紹一種非常常用的編碼utf8. 什么是utf-8, 看定義, UTF-8 stands for Unicode Transformation Format-8. It is an octet (8-bit) lossless encoding of Unicode characters

    至于utf8的具體細節和好處,網上一搜一大堆。基本上現在的網頁用的都是utf-8編碼,數據庫里面用的很多也是utf-8,網絡傳輸也是很多使用utf8。反正我覺得utf8的使用率是非常高的。比如我們想把一個字符串存入本地文件的時候也可以使用utf8編碼,當然也使用ANSI或者UNICODE. 這里就簡單介紹一下C++和Java里面的utf8使用吧。在C++里面,現在可以使用C++11了,簡單的一個例子,把一個unicode字符串轉換成utf8,再把utf8轉換成unicode

    [cpp] view plaincopyprint?
  • #ifndef UNICODE?
  • #define UNICODE?
  • #endif?
  • ?
  • #include "stdafx.h"?
  • #include <windows.h>?
  • #include <stdio.h>?
  • #include <locale>?
  • #include <codecvt>?
  • #include <fstream>?
  • ?
  • #include <string>?
  • ?
  • using namespace std;?
  • ?
  • // convert UTF-8 string to wstring?
  • std::wstring utf8_to_wstring (const std::string& str)?
  • {?
  • ??? std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;?
  • ??? return myconv.from_bytes(str);?
  • }?
  • ?
  • // convert wstring to UTF-8 string?
  • std::string wstring_to_utf8 (const std::wstring& str)?
  • {?
  • ??? std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;?
  • ??? return myconv.to_bytes(str);?
  • }?
  • ?
  • int main()?
  • {?
  • ??? // UTF-8 narrow multibyte encoding?
  • ??? std::string ansi = "程序員";?
  • ??????????????
  • ??? std::wstring unicode(L"程序員");?
  • ??? const wchar_t* p = unicode.c_str();?
  • ?????
  • ??? std::string utf8 = wstring_to_utf8(unicode);?
  • ????
  • ??? std::wstring unicode2 = utf8_to_wstring(utf8);?
  • }?
  • #ifndef UNICODE #define UNICODE #endif#include "stdafx.h" #include <windows.h> #include <stdio.h> #include <locale> #include <codecvt> #include <fstream>#include <string>using namespace std;// convert UTF-8 string to wstring std::wstring utf8_to_wstring (const std::string& str) {std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;return myconv.from_bytes(str); }// convert wstring to UTF-8 string std::string wstring_to_utf8 (const std::wstring& str) {std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;return myconv.to_bytes(str); }int main() {// UTF-8 narrow multibyte encodingstd::string ansi = "程序員";std::wstring unicode(L"程序員");const wchar_t* p = unicode.c_str();std::string utf8 = wstring_to_utf8(unicode);std::wstring unicode2 = utf8_to_wstring(utf8); }運行一下,可以看到utf8的字節流,然后再把utf8字節流轉換成UNICODE得到unicode2,unicode2顯示的也是“程序員”。

    如果用C#就更簡單了。我們可以看到utf8編碼的字節流跟C++的一模一樣。

    最后看一下c#源文件的編碼,我這里的c#源文件編碼用的是UNICODE, 看圖:(好像如果有中文的話,VS會轉換成utf8)


    盡量不要在源代碼文件里面hardcode需要顯示在UI上的字符串

    比如類似的代碼:

    [cpp] view plaincopyprint?
  • string title = "hellow world";?
  • ?
  • SetWindowText(title);?
  • string title = "hellow world";SetWindowText(title);

    這個真的不是好習慣。如果你的程序要支持其他語言的話,你就不得不修改源文件而且重新編譯了。而且萬一需要支持中文的話,那么就得在字符串常量里面寫中文,可是有些時候又不知道源文件是用什么格式來編碼的。比如源文件是用utf8編碼的話,文件就來的,SetWindowText()是不支持utf8編碼顯示的,我們不得不先把utf8編碼轉換成ANSI或者UNICODE,再調用windows API。還有其他問題,比如你用VS UNICODE編碼來寫程序的,而另外一個人用Xcode來寫程序,那么你的中文在他的Xcode里面肯定顯示亂碼。總之很麻煩。我覺得我們的字符串常量應該盡可能放在資源文件里面,比如C++的resource文件,C#的資源文件。android程序也是有資源文件。這樣比較好,如果要改字符串的話,改資源文件就可以了。不需要跟源代碼。當然如果是一些log之類的字符串,寫在源代碼文件里面倒也問題不大,因為這些log通常都是英文,而且沒有localization的問題。


    其他編碼

    除了ANIS, UNICODE, UTF8之后還有很多其他的編碼,但是我覺得這三種是最常用的。而且一旦掌握了這三種以后,再看其他的編碼應該也是很容易了。

    總結

    以上是生活随笔為你收集整理的ANSI,ASCII,UNICODE的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。