如何使getchar()函数保留退格 #包括 内部主(空) { INTC; 而((c=getchar())!=EOF) { 如果(c==8)//8是退格的ASCII值 printf(“\\b”); } }

如何使getchar()函数保留退格 #包括 内部主(空) { INTC; 而((c=getchar())!=EOF) { 如果(c==8)//8是退格的ASCII值 printf(“\\b”); } },c,C,现在我想输入backspace,并希望getchar()函数将backspace的ASCII值返回到c(int变量) 注意-我不是问getch函数,我知道getch命令能够读取backspace 我只想知道getchar是否能够读取backspace 如果是,如何进行 怎么做请给我解释一下 我是C编程新手如果流stdin从文件中读取,则getchar()将像处理任何其他常规字符一样处理退格字符('\b'或ASCII中的8),并将其返回给调用者 当从控制台(也称为终端或tty)读取时,它不这样做的

现在我想输入backspace,并希望getchar()函数将backspace的ASCII值返回到c(int变量)

注意-我不是问getch函数,我知道getch命令能够读取backspace 我只想知道getchar是否能够读取backspace 如果是,如何进行

怎么做请给我解释一下
我是C编程新手

如果流
stdin
从文件中读取,则
getchar()
将像处理任何其他常规字符一样处理退格字符(
'\b'
或ASCII中的8),并将其返回给调用者

当从控制台(也称为终端或tty)读取时,它不这样做的原因与控制台本身的配置有关。默认情况下,控制台处于烹调模式,以便处理回显、退格和行缓冲,还可以处理为Ctrl-C和更多子文件设置发送的信号,如
SIGINT

C标准没有提供任何改变终端模式的方法,但是POSIX系统有命令和系统调用可供C程序使用

在原始模式下配置控制台后,还可以使用
setvbuf(stdin,NULL,_IONBF,0)
stdin
设置为无缓冲模式,以便
getchar()
在键入时从控制台读取每个字节

配置控制台是一个复杂的问题,您可能需要先阅读以下内容:

如果您的系统支持POSIX.1-2001中的标准化,那么您可以操纵标准输入终端以不缓冲您的输入。考虑下面的例子:

#include<stdio.h>
int main(void)
{
    int c;
    while((c=getchar())!=EOF)
    {
        if(c==8)       // 8 is ASCII value of backspace
          printf("\\b");
    }
}
#定义POSIX_C_SOURCE200809L
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*信号处理器*/
静态易失性sig_原子_t done=0;
静态无效句柄_done(int signum)
{
如果(!完成)
完成=信号;
}
静态int安装完成(const int signum)
{
结构动作法;
memset(&act,0,sizeof act);
sigemptyset(和act.sa_面具);
act.sa_handler=handle_done;
act.sa_标志=0;
if(sigaction(signum,&act,NULL)=-1)
返回errno;
返回0;
}
/*将终端恢复到原始设置*/
静态结构termios终端配置;
静态无效终端(无效)
{
tcsetattr(标准输入文件号、TCSAFLUSH和终端配置);
}
内部主(空)
{
INTC;
/*设置INT(Ctrl+C)、TERM和HUP信号处理程序*/
如果(安装完成(SIGINT)||
安装完成(SIGTERM)||
安装完成(SIGHUP)){
fprintf(stderr,“无法安装信号处理程序:%s。\n”,strerror(errno));
返回退出失败;
}
/*使终端输入非规范;非行缓冲。同时禁用回波*/
如果(isatty(标准文件号)){
结构termios配置;
如果(tcgetattr(标准输入文件号和终端配置)=0&&
tcgetattr(标准输入文件号和配置)==0){
config.c_lflag&=~(ICANON | ECHO);
config.c_cc[VMIN]=1;/*阻塞输入*/
config.c_cc[VTIME]=0;
tcsetattr(标准文件号、TCSANOW和config);
atexit(终端);
}
}
/*将标准输入设置为无缓冲*/
setvbuf(标准输入,空,0);
printf(“按Ctrl+C退出。\n”);
fflush(stdout);
而(!完成){
c=fgetc(标准偏差);
如果(c==EOF)
printf(“读取EOF%s\n”,ferror(stdin)?“发生错误时”:“”;
其他的
printf(“读取%d=0x%02x\n”,c,(无符号整数)c);
fflush(stdout);
}
返回退出成功;
}
#define
行告诉您的C库头为基于GNU的系统公开POSIX.1特性

每当接收到INT(Ctrl+C)、TERM或HUP信号时,就会设置
done
标志。(如果您断开与终端的连接,例如关闭终端窗口,则会发送HUP信号。)

terminal\u config
结构将包含原始终端设置,由注册为退出时功能的
revert\u terminal()
使用,以将终端设置恢复为程序启动时读取的原始设置

如果标准输入是终端,则函数
isatty(STDIN\u FILENO)
返回1。如果是这样,我们将获得当前的终端设置,并针对非规范模式修改它们,并要求每个读取块直到至少读取一个字符。(如果设置
.c_cc[VMIN]=0
.c_cc[VTIME]=0
,I/O函数往往会有点混乱,因此如果没有待处理的输入,
fgetc()
返回0。通常它看起来像是对stdio.h I/O函数的EOF。)

接下来,我们使用
setvbuf()
告诉C库不要在内部缓冲标准输入。通常,为了提高效率,C库对标准输入使用输入缓冲区。然而,对我们来说,这意味着C库将缓冲键入的字符,而我们的程序在键入字符时可能不会立即看到它们

类似地,标准输出也被缓冲以提高效率。C库应该将所有完整的行刷新到实际的标准输出,但是我们可以使用
fflush(stdout)
调用来确保我们写入stdout的所有内容都刷新到实际的标准输出

main()
中,我们有一个简单的循环,它读取按键,并以十进制和十六进制打印它们

请注意,当传递信号时,例如由于键入Ctrl+C而导致的INT信号,如果有一个调用挂起,则将信号传递到我们的
handle\u done()
信号处理程序会中断
fgetc()
调用。这就是为什么按Ctrl+C时会看到
读取EOF
;如果随后选中ferror(stdin),您将看到它返回非零(这表示发生了错误)。这种情况下的“错误”是
EINTR#define  _POSIX_C_SOURCE  200809L
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

/* SIGINT handler */

static volatile sig_atomic_t  done = 0;

static void handle_done(int signum)
{
    if (!done)
        done = signum;
}

static int install_done(const int signum)
{
    struct sigaction  act;
    memset(&act, 0, sizeof act);
    sigemptyset(&act.sa_mask);
    act.sa_handler = handle_done;
    act.sa_flags = 0;
    if (sigaction(signum, &act, NULL) == -1)
        return errno;
    return 0;
}

/* Reverting terminal back to original settings */

static struct termios  terminal_config;

static void revert_terminal(void)
{
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &terminal_config);
}


int main(void)
{
    int  c;

    /* Set up INT (Ctrl+C), TERM, and HUP signal handlers. */
    if (install_done(SIGINT) ||
        install_done(SIGTERM) ||
        install_done(SIGHUP)) {
        fprintf(stderr, "Cannot install signal handlers: %s.\n", strerror(errno));
        return EXIT_FAILURE;
    }

    /* Make terminal input noncanonical; not line buffered. Also disable echo. */
    if (isatty(STDIN_FILENO)) {
        struct termios  config;
        if (tcgetattr(STDIN_FILENO, &terminal_config) == 0 &&
            tcgetattr(STDIN_FILENO, &config) == 0) {
            config.c_lflag &= ~(ICANON | ECHO);
            config.c_cc[VMIN] = 1; /* Blocking input */
            config.c_cc[VTIME] = 0;
            tcsetattr(STDIN_FILENO, TCSANOW, &config);
            atexit(revert_terminal);
        }
    }

    /* Set standard input unbuffered. */
    setvbuf(stdin, NULL, _IONBF, 0);

    printf("Press Ctrl+C to exit.\n");
    fflush(stdout);

    while (!done) {
        c = fgetc(stdin);
        if (c == EOF)
            printf("Read EOF%s\n", ferror(stdin) ? " as an error occurred" : "");
        else
            printf("Read %d = 0x%02x\n", c, (unsigned int)c);
        fflush(stdout);
    }

    return EXIT_SUCCESS;
}