在C语言中共享相同ASCII值的两个不同字符
我使用的是带有GCC4.8.1的Linux x86_64 代码:在C语言中共享相同ASCII值的两个不同字符,c,ascii,carriage-return,xterm,linefeed,C,Ascii,Carriage Return,Xterm,Linefeed,我使用的是带有GCC4.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 = %
#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;
}
问题:在上面的程序中,当我输入
Ctrl+J
(换行符)时,它会吐出10,这确实是\n
的ASCII,但当我输入Ctrl+M
(回车符)时,它也吐出10而不是13(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
我不知道^J键盘快捷键,但我敢打赌,如果您在代码中输入固定字符(不是从终端读取)'\r'和'\n',您将获得正确的ASCII值。这意味着要么是你的终端设置像@alk said一样出错,要么是^J没有做你认为它能做的事…我不知道^J键盘快捷键,但我敢打赌,如果你用固定字符(不是从终端读取的)'\r'和'\n'输入代码,你会得到正确的ASCII值。这意味着要么是您的终端设置错误,比如@alk said,要么是^J没有做您认为它能做的事…问题在于,在终端驱动程序中启用了
ICRNL
。以下是tcsetttr(3)
手册页中的一个片段,用于从C设置终端属性:
ICRNL
在输入时将回车转换为换行符(除非设置了IGNCR
)
要禁用ICRNL
,可以在程序运行之前运行以下命令(或直接使用tcsetattr()
):
stty-a
用于查看当前终端设置
请注意,上述操作也会阻止Enter键正常工作(因为它会生成回车,而终端驱动程序正在等待换行符在发送到程序之前终止该行)。您将不得不使用Ctrl-J来代替。:)
如果您感兴趣的话,下面是关于为什么在禁用了IGNCR
的情况下(至少在Bash中)Return仍然在shell中工作的切线:
Bash使用库读取命令。在读取命令之前,readline将终端置于非规范模式,在该模式下,输入是无缓冲的(可以一次读取一个字符,只要键入一个字符)。因此,readline会在键入回车字符后立即看到它,并将其作为行终止符接受
非规范模式需要实现华丽的线条编辑,比如能够用光标键移动光标,并在命令的中间插入文本。文本UI库(如)也使用此模式
当您的C程序运行时,终端处于规范模式,终端驱动程序执行行缓冲(每次向进程发送一行输入)。此模式仅支持基本的行编辑(例如,支持擦除),不解释光标键,这就是为什么按下光标键时屏幕上会出现奇怪的字符序列。(这些字符是由光标键生成的,在这种模式下,光标键变得可见。一个方便的命令是一个没有参数的普通cat
。)
通过
ICANON
启用/禁用规范模式,该选项与IGNCR
类似。不过,从shell中尝试它可能有点棘手,因为shell会在程序(如stty
)运行时对其进行设置和重置。问题是在终端驱动程序中启用了ICRNL
。以下是tcsetttr(3)
手册页中的一个片段,用于从C设置终端属性:
ICRNL
在输入时将回车转换为换行符(除非设置了IGNCR
)
要禁用icrl
,可以在程序之前运行以下命令(或直接使用tcseattr()
):
stty-a
用于查看当前终端设置
请注意,上述操作也会阻止Enter键正常工作(因为它会生成回车,而终端驱动程序正在等待换行符在发送到程序之前终止该行)。您将不得不使用Ctrl-J来代替。:)
如果您感兴趣的话,下面是关于为什么在禁用了IGNCR
的情况下(至少在Bash中)Return仍然在shell中工作的切线:
Bash使用库读取命令。在读取命令之前,readline将终端置于非规范模式,在该模式下,输入是无缓冲的(可以一次读取一个字符,只要键入一个字符)。因此,readline会在键入回车字符后立即看到它,并将其作为行终止符接受
非规范模式需要实现华丽的线条编辑,比如能够用光标键移动光标,并在命令的中间插入文本。文本UI库(如)也使用此模式
当您的C程序运行时,终端处于规范模式,终端驱动程序执行行缓冲(每次向进程发送一行输入)。此模式仅支持基本的行编辑(例如,支持擦除),不解释光标键,这就是为什么按下光标键时屏幕上会出现奇怪的字符序列。(这些字符是由光标键生成的,在这种模式下,光标键变得可见。一个方便的命令是一个没有参数的普通cat
。)
通过
ICANON
启用/禁用规范模式,该选项与IGNCR
类似。不过,从shell中尝试它可能有点棘手,因为shell会在程序(如stty
)运行时对其进行设置和重置。@alk-我正在使用xterm。@rootkea:我添加了一个(长)说明,说明为什么在禁用ICRNL
的情况下,Return仍然在shell中工作。我想这可能有点让人困惑。@alk-我正在使用xterm。@rootkea:我添加了一个(长)n
$ 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
$ stty -icrnl