c - Unix(Mac OS)终端不将 Ctrl+D 视为 EOF
问题描述
我遇到的问题:当我玩getchar()
行为时,我发现我的终端(macOS Mohave 版本 10.14.6 18G87)不支持 Ctrl+D 作为 EOF。
我是如何遇到问题的:
下面附上代码getchar()
,基本上这个代码是 echo getchar() 如果输入字符不是空白,否则,对于多个连续空白字符,它只输出一个空白字符。代码本身可以工作,但是在终端中运行它时,终端不会将 Ctrl+D 视为 EOF,因此代码永远不会终止。
我确信这是由于我错误地使用了system ("/bin/stty raw");
,system ("/bin/stty cooked");
但是,我不知道如何修复它。
/* K&R C Exercise 1-9. Write a program to copy its input to its output,
* replacing each string of one or more blanks by a single blank.*/
#include <stdio.h>
#include <stdlib.h>
int main(void){
int ch;
int prev = -1;
/* if you are in a UNIX like environment
* the ICANON flag is enabled by default, so input is buffered until the next '\n' or EOF
* https://stackoverflow.com/a/1799024/5450745
* */
system ("/bin/stty raw");
while ((ch=getchar())!= EOF){
if (ch != ' ' ){
if (prev == ' '){
putchar(prev);
putchar(ch);
}
else{
putchar(ch);
}
prev = ch;
}
else{
prev = ch;
continue;
}
}
/* use system call to set terminal behaviour to more normal behaviour */
system ("/bin/stty cooked");
return 0;
}
我检查了stty
,但是,它确实配置EOF
为Ctrl +D
. 但是,现在,如果我按Ctrl + D
,它只会将终端从一个窗口拆分为两个。
我可以做些什么来允许EOF
重新启用?
谢谢!
解决方案
此代码适用于我运行 macOS Catalina 10.15 的 Mac。我希望它在几乎任何你可以使用的类 Unix 系统上都能正常工作,包括旧版本的 macOS。它control-D通过ch
与'\004'
(八进制 4 — 在标准 C 中可写的许多其他方式,包括 just 4
)进行比较来发现,在键入并终止循环时被检测到。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ch;
int prev = -1;
/* if you are in a UNIX like environment
* the ICANON flag is enabled by default, so input is buffered until the next '\n' or EOF
* https://stackoverflow.com/a/1799024/5450745
* */
system("/bin/stty raw");
while ((ch = getchar()) != EOF && ch != '\004')
{
if (ch != ' ')
{
if (prev == ' ')
{
putchar(prev);
putchar(ch);
}
else
{
putchar(ch);
}
prev = ch;
}
else
{
prev = ch;
continue;
}
}
/* use system call to set terminal behaviour to more normal behaviour */
system("/bin/stty cooked");
return 0;
}
当然,输出显示有点奇怪——return例如,键入不会将光标移动到下一行。但是测试ch == '\004'
确实检测到何时control-D输入。(空格消除代码也可以。)
使用stty cbreak
而不是stty raw
使中断启用,但 EOF viacontrol-D仍然被禁用。
推荐阅读
- python - 从python中的文本文件导入输入
- swift - swift 如何从我们在文档目录中创建的子文件夹中获取所有文件?
- java - 如何从 cxf outInterceptor 获取响应正文
- javascript - 拉动刷新不会在特定屏幕上禁用(React js)
- c++ - Qt没有完整的头文件是有原因的吗?
- c++ - 从函数返回向量以打印内容
- azure - 如何在进行 nslookup 时隐藏非权威答案
- node.js - 在刷新 NodeJs 时丢失会话
- excel - 字符串中的 VBA EXCEL 公式
- flutter - Flutter TextEditingController 保留值而不点击完成按钮