【发布时间】:2011-08-30 18:28:00
【问题描述】:
我正在为大学作业编写一个小型 C 程序,我注意到我的代码中有一个奇怪的错误。我通常使用带短键盘的 iMac,但它的电池没电了,所以我插入了带数字键盘的标准 USB 键盘。
奇怪的是,如果我在数字键盘上按 [Enter],它似乎会执行常规 [Enter} 键的作用,但是我试图在我为读取键盘输入而创建的 stdin 函数,当我使用数字键盘的 [Enter] 键时不起作用。
什么?
这是我读取用户输入的函数:
/* This is my implementation of a stdin "scanner" function which reads
* on a per character basis until the the termination signals are found
* and indescriminately discarding all characters in the input in excess
* of the supplied (limit) parameter. Eliminates the problem of 'left-over'
* characters 'polluting' future stdin reads.
*/
int readStdin(int limit, char *buffer)
{
char c;
int i = 0;
int read = FALSE;
while ((c = myfgetc(stdin)) != '\n' && c != '\0') {
/* if the input string buffer has already reached it maximum
limit, then abandon any other excess characters. */
if (i <= limit) {
*(buffer + i) = c;
i++;
read = TRUE;
}
}
/* clear the remaining elements of the input buffer with a null character. */
for (i = i; i < strlen(buffer); i++) {
*(buffer + i) = '\0';
}
return read;
}
/* This function used to wrap the standard fgetc so that I can inject programmable
* values into the stream to test my readStdin functions.
*/
int myfgetc (FILE *fin) {
if (fakeStdIn == NULL || *fakeStdIn == '\0')
return fgetc (fin);
return *fakeStdIn++;
}
注意:myfgetc 和随后的*fakeStdIn 是我可以单元测试我的代码并将项目“注入”到标准输入流中的一种方式,正如有人在这个问题上建议的那样:How do I write a testing function for another function that uses stdin input?。
【问题讨论】:
-
为什么不添加调试 printf 语句来查看字符是什么?我的猜测是它是 0x03。
-
请注意,您的
for循环清除缓冲区非常尴尬;i=i值得一笑(您可以将任何表达式留空:for(;;)是无限循环的有效语法)但i < strlen(buffer)假设在分配给buffer的空间中已经有一个'\0'。那可能不是真的。之后通过limit参数清除空间,或者通过limit参数将读取之前的空间清零,但不要使用strlen(buffer)来确定何时终止循环。跨度> -
所以我这样做了,结果没有一个数字键盘键实际上进入标准输入流。它们在控制台中工作,但是当我将数字键盘和非数字键盘字符混合在一起时,char* 中只会出现非数字键盘字符。
-
取决于终端和窗口环境;在我的 X11 下的 Linux 上,
return和kb_enter键都生成'\n'字符(十进制10),但return生成 X11 键符Return,kp_enter生成KP_Enter。在我的环境中,两者都映射到'\n'。你的,显然不同。 :) -
@sarnold - 我正在运行 vanilla OSX 10.6 - 数字键盘键似乎没有映射到任何东西。至少不是标准输入。