[英]Two distinct characters sharing same ASCII value in C
我在gcc 4.8.1中使用Linux x86_64。
碼:
#include <stdio.h>
int main(int argc, char *argv[])
{
int ch;
do
{
printf("ch : ");
ch = getchar(); //Q Why CTRL+M = 10 and not 13?
getchar();
printf("ch = %d\n\n", ch);
}while(ch != 'z');
return 0;
}
輸出:
ch : ^N
ch = 14
ch :
ch = 10
ch :
ch = 10
ch : z
ch = 122
題:
在上面的程序中,當我輸入Ctrl+J
(換行符)時,它吐出10,這實際上是\\n
的ASCII。但是當我輸入Ctrl+M
(回車符)時,它也吐出10而不是13( \\r
ASCII值) \\r
)。
這是怎么回事? \\n
和\\r
是否共享相同的ASCII值? 那么哪個字符代表ASCII 13?
編輯:
$ uname -a
Linux Titanic 3.11.0-26-generic #45-Ubuntu SMP Tue Jul 15 04:02:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
問題是在終端驅動程序中啟用了ICRNL
。 這是tcsetattr(3)
手冊頁中的摘錄,從C使用它來設置終端屬性:
ICRNL
在輸入ICRNL
回車轉換為換行符(除非設置了IGNCR
)。
要禁用ICRNL
,可以在程序之前運行以下命令(或直接使用tcsetattr()
):
$ stty -icrnl
stty -a
可讓您查看當前的終端設置。
請注意,上述操作也會阻止您的Enter鍵正常工作(因為它會生成回車符,而終端驅動程序正在等待換行以終止該行,然后再將其發送給您的程序)。 您將不得不使用Ctrl-J代替。 :)
以下是關於為什么Return仍在禁用IGNCR
(至少在Bash中使用)的情況下仍可在Shell中工作的切線,以防您感興趣:
Bash使用readline庫讀取命令。 在讀取命令之前,readline會將終端置於非規范模式,在該模式下,輸入不會被緩沖(只要鍵入一個字符,一次即可讀取一個字符)。 因此,readline會在鍵入后立即看到回車符,並碰巧將其作為行終止符。
需要非規范模式來實現花哨的行編輯,例如能夠使用光標鍵移動光標並在命令中間插入文本。 文本UI庫(例如ncurses)也使用此模式。
當您的C程序運行時,終端將處於規范模式,在該模式下,終端驅動程序將進行行緩沖(將輸入一次發送至進程一行)。 此模式僅具有基本的行編輯功能(例如,支持擦除),並且不解釋光標鍵,這就是為什么按下鍵時屏幕上會出現奇怪的字符序列的原因。 (這些字符是由光標鍵生成的終端轉義序列 ,在此模式下可見。在此方便進行實驗的命令是沒有參數的普通cat
。)
規范模式通過ICANON
啟用/禁用,這與IGNCR
一樣是一個選項。 但是,從shell進行試驗可能會有些棘手,因為shell會在運行程序(如stty
)時對其進行設置和重置。
我不知道^ J鍵盤快捷鍵,但我敢打賭,如果您使用固定字符(不是從終端讀取)“ \\ r”和“ \\ n”來輸入代碼,則會獲得正確的ASCII價值觀。 這意味着要么是您的終端設置出現問題,如@alk所說的那樣,要么是^ J沒有按照您的想法做...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.