代码是here。当我运行我的程序时(我将kbhit保存为头文件并将其保存在我的程序文件夹中),在第一次使用kbhit (我使用DrMemory进行内存调试)时,我获得了一个未初始化的读访问权限。我包含了sys/ioctl.h,因为我的程序没有它就不能使用FIONREAD。有问题的是对tcsetattr(STDIN,TCSANOW,&term)的调用;我不完全理解它是如何工作的,所以任何帮助都将不胜感激。谢谢!
编辑:确切的消息是“UNINITIALIZED READ: reading 12字节。系统调用ioctl.0x5402参数#2。“这行代码来自tcsetattr()调用。此错误发生在将kbhit保存为cpp文件并将其模板化到另一个文件中之后。程序运行得很好,除了一个错误。
发布于 2019-02-18 14:18:55
这是代码的一个版本,我将其修改为实际的C语言,而不是结构,因为它只是由于疏忽而使用bool true/false和C++关键字进行了C++。
哦,对了,不要把它放在头文件中。将其放入名为kbhit.c的文件中,然后删除或注释掉test main函数。在头文件中,只需写一行:
int _kbhit(void);或者,您可能需要:
extern "C" int _kbhit(void);这就是您在标题中需要的全部内容。
/**
Linux (POSIX) implementation of _kbhit().
Morgan McGuire, morgan@cs.brown.edu
*/
#include <stdbool.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
int _kbhit(void) {
static bool initialized = false;
if (! initialized) {
// Use termios to turn off line buffering
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag &= ~ICANON;
tcsetattr(STDIN_FILENO, TCSANOW, &term);
setbuf(stdin, NULL);
initialized = true;
}
int bytesWaiting;
ioctl(STDIN_FILENO, FIONREAD, &bytesWaiting);
return bytesWaiting;
}
//////////////////////////////////////////////
// Simple demo of _kbhit()
int main() {
printf("Press any key");
while (! _kbhit()) {
printf(".");
fflush(stdout);
usleep(1000);
}
printf("\nDone.\n");
return 0;
}它在我看来是正确的,valgrind没有抱怨。我找不到记忆博士来检查。
这段代码的工作原理是,它首先使用tcgetattr读取termios (我认为是终端输入输出设置)结构。然后,它通过取消设置ICANON位来修改它。Canon是终端的规范设置,其中包括行缓冲。然后,它将新的termios值写回终端。和tcsetattr在一起。
ioctl调用获取缓冲区中等待的字节数。如果有字节在等待,那么就是有人按了某种键。
https://stackoverflow.com/questions/54741213
复制相似问题