Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
';设备的ioctl不适当';C中的错误_C_Getch - Fatal编程技术网

';设备的ioctl不适当';C中的错误

';设备的ioctl不适当';C中的错误,c,getch,C,Getch,我有一个getch()函数,是导师给我的,不用点击“回车”就可以从键盘上输入。但是,当我在Eclipse的Ubuntu12中运行它时,我得到以下错误: tcsetattr(): Inappropriate ioctl for device tcsetattr ICANON: Inappropriate ioctl for device 这是我的代码: #include <stdio.h> #include <unistd.h> #include <termios.

我有一个
getch()
函数,是导师给我的,不用点击“回车”就可以从键盘上输入。但是,当我在Eclipse的Ubuntu12中运行它时,我得到以下错误:

tcsetattr(): Inappropriate ioctl for device
tcsetattr ICANON: Inappropriate ioctl for device
这是我的代码:

#include <stdio.h>
#include <unistd.h>
#include <termios.h>

char getch();

int main(int argc, const char* argv[])
{
    char c;
    do
    {
        c=getch();
        printf("%c",c);
    } while(c!='q');

    return 0;
}

char getch()
{
    char buf = 0;
    struct termios old = {0};
    if (tcgetattr(0, &old) < 0)
        perror("tcsetattr()");
    old.c_lflag &= ~ICANON;
    old.c_lflag &= ~ECHO;
    old.c_cc[VMIN] = 1;
    old.c_cc[VTIME] = 0;

    if (tcsetattr(0, TCSANOW, &old) < 0)
        perror("tcsetattr ICANON");
    if (read(0, &buf, 1) < 0)
        perror ("read()");
    old.c_lflag |= ICANON;
    old.c_lflag |= ECHO;
    if (tcsetattr(0, TCSADRAIN, &old) < 0)
        perror ("tcsetattr ~ICANON");
    return (buf);
}
#包括
#包括
#包括
char getch();
int main(int argc,const char*argv[]
{
字符c;
做
{
c=getch();
printf(“%c”,c);
}而(c!='q');
返回0;
}
char getch()
{
char-buf=0;
结构termios old={0};
if(tcgetattr(0,&old)<0)
perror(“tcSetttr()”);
old.c_lflag&=~ICANON;
old.c_lflag&=~ECHO;
old.c_cc[VMIN]=1;
old.c_cc[VTIME]=0;
if(tcsetattr(0、TCSANOW和old)<0)
佩罗尔(“tcsetattr ICANON”);
如果(读取(0,&buf,1)<0)
perror(“read()”);
old.c|lflag |=ICANON;
old.c|lflag |=回声;
if(tcsetattr(0、TCSADRAIN和old)<0)
佩罗尔(“tcsetattr~ICANON”);
返回(buf);
}
注意:该代码在SSH Secure Shell中不起作用。但是我必须在我的Ubuntu中完成这项工作,因为我在那里写代码。
感谢

这可能是因为Eclipse没有为在IDE下运行的程序提供。尝试这种依赖于非阻塞I/O而不是终端控制的替代方案

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define perror_exit(msg) do { perror(msg); exit(1); } while(0)

#if defined EAGAIN && defined EWOULDBLOCK
#define retry_p(err) ((err) == EAGAIN || (err) == EWOULDBLOCK)
#elif defined EAGAIN
#define retry_p(err) ((err) == EAGAIN)
#elif defined EWOULDBLOCK
#define retry_p(err) ((err) == EWOULDBLOCK)
#else
#error "Don't know how to detect read-would-block condition."
#endif

int
main(void)
{
    int flags = fcntl(0, F_GETFL);
    if (flags == -1)
        perror_exit("fcntl(F_GETFL)");
    flags |= O_NONBLOCK;
    if (fcntl(0, F_SETFL, flags))
        perror_exit("fcntl(F_SETFL, O_NONBLOCK)");

    for (;;)
    {
       char ch;
       ssize_t n = read(0, &ch, 1);
       if (n == 1)
       {
           putchar(ch);
           if (ch == 'q')
               break;
       }
       else if (n < 0 && !retry_p(errno))
          perror_exit("read");
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#定义perror_exit(msg)do{perror(msg);exit(1);}while(0)
#如果定义了EAGAIN和定义了EWOOLDLOCK(&E)
#定义重试(err)((err)==EAGAIN | | |(err)==EWOULDBLOCK)
#伊莱夫·伊格恩
#定义重试(err)((err)=EAGAIN)
#elif定义的块
#定义重试(err)((err)=ewoodblock)
#否则
#错误“不知道如何检测读取将阻塞条件。”
#恩迪夫
int
主(空)
{
int flags=fcntl(0,F_GETFL);
如果(标志==-1)
perror_出口(“fcntl(F_GETFL)”);
标志|=O|U非块;
if(fcntl(0,F_设置,标志))
perror_出口(“fcntl(F_SETFL,O_NONBLOCK)”);
对于(;;)
{
char ch;
ssize_t n=读取(0,&ch,1);
如果(n==1)
{
putchar(ch);
如果(ch='q')
打破
}
否则如果(n<0&!重试p(错误号))
perror_出口(“读取”);
}
返回0;
}
如果此操作仍然不起作用,请尝试修改它,使其同时执行此操作和
getch()
的操作,忽略
tcsetattr
tcgetattr
errno==ENOTTY
时的失败


请注意,这段代码和原始代码都在忙着等待I/O,这是一种糟糕的做法。你真正应该做的是使用这个库,它有一种更复杂的方法来同时处理和等待输入,更适合多任务环境,还可以解决你的缺乏tty的问题和其他一些你不想浪费精力的低级问题。

,如果它没有伪终端,那么从0读取的底层数据将被阻塞,因为它是一个管道。感谢您的努力。我还试着从终端运行它。终端是否缺少Eclipse所缺少的相同属性?或者它应该在那里工作?原始程序应该在任何称自己为“终端”的上下文中工作。我可以想象,由于实现“终端”的特定程序或您正在使用的特定操作系统的微妙之处,它会失败。这正是
ncurses
将为您解决的问题。