首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何避免按任何getchar()输入

如何避免按任何getchar()输入
EN

Stack Overflow用户
提问于 2018-04-13 06:50:22
回答 2查看 0关注 0票数 0

这是C编程语言的“novato”问题:

在下一个代码中:

代码语言:javascript
复制
#include<stdio.h>

int main(void){   
  int c;   
  while((c=getchar())!= EOF)      
    putchar(c); 
  return 0;
}

我必须按Enter来显示我输入的所有字母getchar,但我不想这样做,我想要做的就是按下该字母,然后立即看到我重复介绍的字母,而不是按下Enter。例如,如果我按字母'a',我想在其旁边看到另一个'a',依此类推:

代码语言:javascript
复制
aabbccddeeff.....

但是当我按下'a'时什么都没有发生,我可以写其他字母,只有当我按下时才会出现副本Enter:

代码语言:javascript
复制
abcdef
abcdef

我怎样才能做到这一点?

我正在使用cc -o example example.cUbuntu下的命令进行编译。

EN

回答 2

Stack Overflow用户

发布于 2018-04-13 15:07:35

在Linux系统上,你可以使用该stty命令修改终端行为。默认情况下,终端将缓存所有信息直到Enter按下,甚至在将其发送到C程序之前。

代码语言:javascript
复制
#include<stdio.h>

int main(void){
  int c;
  /* use system call to make terminal send all keystrokes directly to stdin */
  system ("/bin/stty raw");
  while((c=getchar())!= '.') {
    /* type a period to break out of the loop, since CTRL-D won't work raw */
    putchar(c);
  }
  /* use system call to set terminal behaviour to more normal behaviour */
  system ("/bin/stty cooked");
  return 0;
}

请注意,这并不是最佳选择,因为它只是假设stty cooked程序退出时的行为,而不是检查原始终端设置。另外,由于所有特殊处理都会在原始模式下跳过,因此许多按键序列(如CTRL-CCTRL-D)实际上并不像你期望的那样在未在程序中明确处理它们的情况下正常工作。

你可以man stty更好地控制终端行为,具体取决于你想实现的目标。

票数 0
EN

Stack Overflow用户

发布于 2018-04-13 16:10:44

这取决于你的操作系统,如果是在类似UNIX的环境中,则默认启用ICANON标志,因此输入将被缓冲,直到下一个‘\n’或EOF。通过禁用规范模式,你将立即获得字符。这在其他平台上也是可能的,但是没有直接的跨平台解决方案。

编辑:我看到你指定使用Ubuntu。我昨天刚刚发布了类似的内容,但请注意,这将禁用你的终端的许多默认行为。

代码语言:txt
复制
#include<stdio.h>
#include <termios.h>            //termios, TCSANOW, ECHO, ICANON
#include <unistd.h>     //STDIN_FILENO


int main(void){   
    int c;   
    static struct termios oldt, newt;

    /*tcgetattr gets the parameters of the current terminal
    STDIN_FILENO will tell tcgetattr that it should write the settings
    of stdin to oldt*/
    tcgetattr( STDIN_FILENO, &oldt);
    /*now the settings will be copied*/
    newt = oldt;

    /*ICANON normally takes care that one line at a time will be processed
    that means it will return if it sees a "\n" or an EOF or an EOL*/
    newt.c_lflag &= ~(ICANON);          

    /*Those new settings will be set to STDIN
    TCSANOW tells tcsetattr to change attributes immediately. */
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    /*This is your part:
    I choose 'e' to end input. Notice that EOF is also turned off
    in the non-canonical mode*/
    while((c=getchar())!= 'e')      
        putchar(c);                 

    /*restore the old settings*/
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);


    return 0;
}

你会注意到,每个角色都会出现两次。这是因为输入立即回显到终端,然后您的程序也用putchar()将其放回。如果要将输入与输出分离,还必须转回回波标志。只需将适当的行更改为:

代码语言:txt
复制
newt.c_lflag &= ~(ICANON | ECHO); 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100008101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档