1樓:omnipotent
有點感興趣,之前自己也想過,寫了個小程式
#include
#include
int main()
putchar('\n');
}這個樣例輸出「測試小程式」五個字。
其中陣列a儲存5組的資料,每組有3個char,最後的乙個0為臨界
那麼——很明了,這5個字在UTF-8的編碼中分別用每組的3個byte來表示。usleep是延遲,使得在for迴圈中,每100ms一次輸出乙個字元。在實際執行下,為每300ms出現乙個漢字。
懂我的意思了吧,C++不知道你輸出的是什麼語言,他只知道乙個位元組乙個位元組的輸出。輸出成什麼樣子,由終端決定。終端會把這3個byte解析為漢字。
但在不支援utf-8編碼的終端中或者終端沒有合適的中文字型,同樣的程式,會輸出亂碼或者其他奇怪的東西。
那麼回到問題。題主問C++如何判斷輸出的是漢字,我把它理解為如何用c++判斷字元為漢字。
你可否注意,在樣例中,在每個漢字的3個byte中,第乙個byte總以0xe開頭。可不可以用這個特徵,來判斷是否為漢字呢?
#include
#include
int main()
printf("\n%d\n",count);
}在這個樣例中,a為乙個字元指標,指向乙個字串。在這個字串中,漢字有27個。我在期間混進了一些英文,程式可以通過這種方法過濾掉英文,輸出中文。
題外話,知乎怎麼改縮排?
2樓:Xi Yang
系統怎麼知道要兩個位元組兩個位元組來輸出漢字
本質上來講,因為不管是GBK還是UTF-8,都是變長編碼,並且1位元組的部分相容ASCII。
如果你整個世界都工作在UTF-16上,那你給ASCII就原地自爆了。
3樓:chenc
c輸出的時候就是乙個位元組乙個位元組輸出的,如果是%s輸出乙個串,那就是全部輸出到了控制台,具體顯示什麼,是控制台決定的。
都未必是2個位元組乙個漢字,比如utf8編碼。如果乙個串是utf8的,而控制台設定了顯示utf8的編碼,那麼用c輸出utf8串就可以正常顯示utf8的漢字。
從某種意義上說c是最不容易亂碼的語言,就是因為它不怎麼智慧型,到底要輸出什麼編碼的串完全由程式設計師自己決定,底層不做亂七八糟的自動轉換。
注意如果想自動適應控制臺編碼,可以使用wprintf或者使用printf的%ls格式,可以根據設定的locale自動進行編碼轉換。
4樓:pansz
輸出函式不需要判斷語言。語言是由顯示裝置負責判斷的。
由程式輸出到顯示裝置的時候,使用的是【傳輸編碼】,顯示裝置顯示的時候,要把傳輸編碼轉化為用於顯示的內碼,而對於內碼怎麼顯示,又是個複雜的問題了,如果排除unicode裡面那些規則複雜蛋疼的多字元組合規則,僅僅考慮常規中文字元的話,那麼每個中文轉化為內碼後都只有乙個字元,而這個字元就直接對應字型庫中的字元,顯示起來也就很自然。總之,顯示環節與輸出環節是解耦的,顯示環節負責進行解碼,如果它的解碼能力不足,支援的格式有問題,無法對應到字型庫中的正確字元,或者字型庫缺少相應字元,那麼就可能是亂碼。
如果顯示裝置是終端,就由終端負責轉換,是圖形介面就由介面負責轉化。就是這樣。
至於顯示裝置如何解碼,那就取決於具體的編碼了。比方說對於 utf8 編碼來說,高位為 1 開頭的是控制碼,這裡的控制碼將指定後續連續字元編碼的長度。對於 gb2312 編碼來說,高位為 1 的是雙位元組碼。
因為 ASCII 編碼本身是 7bit 編碼,所以最高位的第 8 bit 被各種編碼用於控制位。詳情可以查閱不同編碼的資料進行理解。
5樓:littleNewton
通常情況下,所有編碼必須向後相容 ASCII(讀作「阿斯克伊~」)碼。ASCII 也是最早的通用編碼。
要講清楚這個問題,需要從代數編碼角度入手,首先闡明乙個概念,叫做即時可解碼。即時可譯是乙個形容詞。這種編碼比較苛刻,它可以滿足這種解碼情形:
發電報的人給接收者傳送位元組流,接收者在無雜訊(100%正確收到)的情況下可以一邊接收、一邊解碼。
記住,以上這一點是很關鍵的,因為某些編碼做不到這一點,它們必須完整收到所有的位元組才可以解碼,比如某些卷積碼就不能即時可譯。
好,我們回過頭來看程式執行過程中,系統是如何把二進位制串對映到符號串的。咱們以 utf-8 編碼為例,看看系統是如何解碼的。再次明確,utf-8 是一種相容 ASCII 的編碼。
換言之,ASCII 是 utf-8 的子集,A、B、...、Z、1、2、...、9、0 等字元,在 ASCII 中用哪些二進位制串表示,在 utf-8 中就用哪些表示。
另外還有一點,ASCII 是不等長編碼,常用的字元用短碼,不常用字元用長碼表示。
utf-8 編碼乙個字元,最少用 1 byte,最多用 4 byte。
utf-8,只需要看乙個字元的前面 5 個位元就能判斷這是什麼類字元!
那麼來看上面這個圖,可以看到,為了讓 utf-8 能相容 ASCII 碼,所有的單 byte 編碼被完整地留給了 ASCII,而且字首為 0,接下來就是兩 byte 編碼,可以想到,如果兩位元組碼的 Byte 1 和單位元組碼一樣,那麼就不能即時可解碼了!因為你拿到乙個字元,光看前 5 位元是無法區分這是單位元組碼的碼還是兩位元組碼。所以,根據這個原理,必須讓四種不等長的 utf-8 編碼採用的字首彼此都不同!
所以,到了這裡你就明白了,作業系統在執行 print syscall 時,拿到一串二進位制,先取前 5 bit,如果這 5 位元的首個 bit 是 0,那麼不用問,這一定是 ASCII中的,如果前三個是 110,那麼一定是兩位元組編碼,取出倆位元組進行解碼即可,後面以此類推。
懂了吧小伙汁!
6樓:「已登出」
這其實是跟你檔案儲存的編碼有關係,比如說你可以做乙個試驗。你用utf寫乙個檔案,把它用gbk開啟。它會亂碼,你用u tf寫乙個檔案,然後用gbk開啟把它執行,它依然是亂碼,也就是說問題所在其實是你檔案儲存的格式。
C語言 如何輸出回文 比如輸入1234,輸出4321 ?
char InPut char Str int MaxLen char End MaxLen 1 Str charCh char p for p Str p p 0 return p intReflect char Str int MaxLen for char p end Str p printf...
為什麼 C 語言的輸入輸出函式比 C 的輸入輸出流要快?
nolanzz 用流輸出的話,貌似用cerr會比cout更快一些 提醒使用std ios sync with stdio false 這個會導致流讀寫和標準讀寫不能混用,oj上讀寫會出現問題,我本地使用clang貌似沒有問題 cin cout這些不能和scnaf printf這些一起用 Isaac ...
C 語言如何判斷等差數列?
立強 由於 若個數和累加合相同,則等差數列的平方和最小。所以,空間複雜度是O 1 時間複雜度是O n 好吧,再詳細點 遍歷過程需要產生5個值 最大值,最小值,個數,累加合,平方和。例如6個數 最大值6,最小值1,累加和21,平方和等於1 4 9 16 25 36,則是等差數列,否則不是 Milo Y...