c - 如何测试我自己的 kbhit() 替代方案的源代码?
问题描述
我遇到了这段代码,它应该new_kbhit()
为 DOS 函数创建一个替代 POSIX 函数 () kbhit()
。
// Standard C headers
#include <stdio.h>
#include <stdbool.h>
// POSIX system headers
#include <sys/select.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <stropts.h>
/////////////////////////////////////////////////////////////
// FUNCTION: kbhit_new()
//
// It returns 0. But if a key is pressed it returns number
// of pending bytes.
/////////////////////////////////////////////////////////////
int new_kbhit() {
// Stdin's file descriptor (fd) is always 0, stdout's is 1 and stderr's is 2.
static const int stdin_fd = 0;
// This is static because we only want to disable buffering when this function is 1st called.
static bool initialized = false;
// Define the terminal structure named term.
struct termios term;
// Define an integer that will store the number of pending bytes.
int bytes_waiting;
if (! initialized) {
// Get parameter STDIN of the terminal and store it inside termios structure (term).
tcgetattr(stdin_fd, &term);
// A: Remove termios structure's (term) flag ICANON inside the local modes i.e. c_lflag.
// B: Removing flag ICANON will dissable canonnical processing.
// C: When there is no canonical processing
term.c_lflag &= ~ICANON;
// Set terminal's attributes immediately (TCSANOW). Attributes are applied from termios (term).
tcsetattr(stdin_fd, TCSANOW, &term);
// Assign a buffer NULL to stream stdin. This disables buffering on stdin so pressed key is shown.
setbuf(stdin, NULL);
initialized = true;
}
// A: ioctl operates on the "streams devices" but it needs it's file descriptors (fd)..
// B: Linux is not 100% POSIX compliant. It supports more than POSIX defines.
// C: Linux supports "streams device" FIONREAD (https://www.kernel.org/doc/html/latest/)
// C: FIONREAD device stores an integer i.e. "pending number of bytes" in last argument of ioctl.
ioctl(stdin_fd, FIONREAD, &bytes_waiting);
return bytes_waiting;
}
/////////////////////////////////////////////////////////////
// EXAMPLE:
/////////////////////////////////////////////////////////////
#include <unistd.h>
int main(int argc, char** argv) {
printf("Press any key to terminate:\n");
while (! new_kbhit()) {
putchar('.');
fflush(stdout);
usleep(1000000);
}
printf("\nDone.\n");
return 0;
}
使用 POSIX 标准,我以某种方式破译了这段代码的作用(评论)。但对我来说,如果我注释掉函数内的几乎所有内容,它的作用完全一样new_kbdhit()
,看起来像这样:
int new_kbhit() {
int bytes_waiting;
ioctl(stdin_fd, FIONREAD, &bytes_waiting);
return bytes_waiting;
}
所以我无法确认这段代码有什么作用。我如何测试它以了解它的真正潜力?我很难理解它的价值。
解决方案
推荐阅读
- vue.js - v-bind 的自定义 Vue 指令
- flutter - Flutter:如何在razorpay_flutter中提取支付方式?
- postgresql - 如何在 PostgreSQL 的触发器中获取新表名
- node.js - NPM 无法在 Windows 10 主机上的 Ubuntu 下处理 Virtualbox 共享文件夹
- php - 在重量 WooCommerce 之前添加文本
- sql - 使用 SQL(也可能是正则表达式)从列中提取部分数据
- reactjs - 在 React 中一段时间后 SVG 图标没有显示?
- android - 带有 Action.submit 的 AdaptiveCard 按钮在 Android 设备上不起作用
- javascript - RXJS - 嵌套 concapMap 是否等同于顺序 concatMap?
- python-3.x - 未找到具有给定名称和参数类型的函数。为什么我不能在 mtm 字段中搜索 trigram?