在C语言中共享相同ASCII值的两个不同字符

在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 = %

我使用的是带有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 = %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