为什么 getch 不可移植?

2024-05-10

是什么使得 getch 本质上无法作为标准 C 函数包含在内?

对于控制台界面来说,它是如此直观和优雅。如果没有它,要求输入单个字符总是会产生误导,因为用户可以输入多个键。

更糟糕的是,您经常需要确保在读取控制台输入后清除标准输入,这甚至不是作为标准功能提供的!我得用我自己的!

一个简单的程序可以是:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> 
#include <conio.h>

int main(int argc, char **argv)
{   
    while (1) {
        char yes_or_no;        

        printf("is this statement correct? 1 + 1 = 2(Y/N) $ ");
        yes_or_no = tolower(getch());

        switch (yes_or_no) {
            case 'y':
                puts("Right!");     
                goto done;

            case 'n':
                puts("\nhint> Please just say yes for the sake of this demo...");
                break;

            case 'q':
                puts("\nExitting.");
                goto done;

            case EOF:
                puts("\nEOF.");
                goto done;

            default:
                printf("\nunknown response '%c'.\n", yes_or_no);
                break;
        }
    }


done:
    return 0;
}

becomes:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> 

static inline void flush_stdin()
{
    char ch;

    do {
        ch = getchar();
    } while ((ch != '\n') && (ch != EOF));
}

int main(int argc, char **argv)
{   
    while (1) {
        char yes_or_no;        

        printf("is this statement correct? 1 + 1 = 2(Y/N) $ ");
        yes_or_no = tolower(getchar());


        switch (yes_or_no) {
            case 'y':
                puts("Right!");     
                goto done;

            case 'n':
                puts("hint> Please just say yes for the sake of this demo...");
                break;

            case EOF:
                puts("EOF.");
                goto done;

            default:
                printf("unknown response '%c'.\n", yes_or_no);
                break;
        }
        flush_stdin(); /* remove this to see the difference */        
    }


done:
    return 0;
}

每次我想要制作一个简单的便携式控制台程序时,我都会觉得被迫制作一堆类似的功能,但最终仍然没有得到我想要的所有东西,比如 getch。

当然,您可以使用curses,但是curses接管您的整个控制台,并使您的程序的行为与普通用户期望的不同(程序只是滚动,并且仍然在控制台缓冲区中显示您运行程序的命令) 。

我知道“为什么”是一个坏问题(什么应该始终是首选),但必须问。 getch 中有什么本质上不可移植的东西吗?desktop系统不支持?如果没有,我可以自己编写并将其移植到我想要支持的所有平台上,这样就很好。

如果 getch 所做的某些事情无法得到支持desktop系统,是什么?因此,我有更好的理由理解为什么避免使用 conio,而不是“仅使用 ncurses/conio 不是标准”。


C 标准没有终端或 Windows 的概念。与这些事情相关的任何内容都是特定于实现的,不能成为 C 编程语言的一部分。

然而,终端编程有行业标准。一种是 POSIX (IEEE 1003.1) 的一部分,作为termios终端驱动程序接口,一个是 X/Open Curses,它指定了一个 C 函数库来在更高级别上操作终端,第三个是 ISO 6429,一组 ANSI 终端转义序列。

顺便说一句,X/Open 诅咒提供了getch()功能。 Microsoft Windows 也支持这些标准,但不是以一种有用的方式。

你会使用的方式getch()在 Windows 上(即通过conio.h) 是不可移植的,因为conio.h是 DOS 特定的标头,由于控制台在 DOS 中的工作方式与其他平台上的终端的工作方式不同,因此无法在其他平台上轻松实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 getch 不可移植? 的相关文章

随机推荐

  • 我可以使用 :hover 触发 CSS3 动画(或过渡),即使鼠标不再悬停,该动画也会继续运行

    我正在创建一个链接列表 其中一个链接容器在悬停时会展开 包含详细信息 图像和说明 我用 CSS 过渡或动画来制作动画没有任何问题 问题是我希望它即使在鼠标移开后也能保持展开状态 我想在没有 JavaScript 的情况下做到这一点 那可能吗
  • C# XML 反序列化。将节点中的所有内部文本读取到字符串属性中

    我目前正在尝试修改我的类 以便我的模型上的文本属性包含某个节点的所有内部文本 text node 给我带来问题的 xml 示例是
  • 如何缓存 ASP.NET 网站以获得更好的性能

    我是一名网页设计师 通常设计不需要更新的企业网站 所以我想将输出缓存一天 我怎样才能做到这一点 此外 任何有关在慢速服务器上提高 ASP NET 性能的建议都被接受 请注意 ASP NET 缓存有一个bug http connect mic
  • React Native 运行保持在 IDLE 状态

    这是我第一次设置 React NativeUbuntu 18 04 LTS 我已经完成设置 并且尝试使用以下命令在设备上运行该应用程序react native run android命令 这是我在终端中得到的输出 ron lenovo re
  • OpenSSL:无需 SSL_read() / SSL_write() 即可执行加密/解密

    我已经用 C 语言编写了一个基于事件的网络库 现在我想通过 OpenSSL 添加 SSL TLS 支持 而不是使用SSL read and SSL write 我宁愿让 OpenSSL 只执行传出 传入数据的加密 解密 让我自己传输 接收数
  • 有没有用 Javascript 编写的开源 JSDoc 解析器?

    我正在寻找一个可以在我的项目中使用的 JSDoc 解析器 我正在寻找可以传递 JSDoc 注释并接收该注释含义的结构化描述的东西 我见过的大多数工具似乎都能够将 JSDoc 注释转换为 HTML 或其他格式 我正在寻找能够提供可用于输入其他
  • 使用 NSCoder 编码 CGPoint 结构

    如何编码和解码CGPoint结构使用NSCoder 编码 CGPoint point point from somewhere NSValue pointValue NSValue value point withObjCType enco
  • 为什么在 C++ 类中的数据成员上使用像 m_ 这样的前缀?

    许多 C 代码使用语法约定来标记数据成员 常见的例子包括 m memberName对于公共成员 在所有使用公共成员的情况下 memberName对于私人会员或所有会员 其他人尝试强制使用this gt member每当使用数据成员时 根据我
  • 如何在不打开邮件的情况下加载 Gmail 插件

    我们需要开发 gmail 插件来读取已检查的邮件消息并处理内容 我们使用以下应用程序 json oauthScopes https www googleapis com auth gmail addons execute https www
  • 提升shared_from_this<>()

    有人可以用几句话概括一下如何提升shared from this lt gt 应该使用智能指针 特别是从使用绑定函数在 io service 中注册处理程序的角度来看 编辑 一些回复要求提供更多背景信息 基本上 我正在寻找 陷阱 即人们使用
  • 智能感知不显示评论

    如果我在 Visual Studio 2010 中输入类似的内容数据集1 我得到所有可用方法和属性的列表 智能感知 这很好用 但是 如果我在此列表中选择一个方法或属性 我不会得到 if 的描述 例如 如果我有类似的东西 public cla
  • 为什么spring boot 1.5.3 jar无法识别src/main/resources/META-INF/resources/中的jsp文件

    我使用了spring boot jsp 我想构建一个可执行的jar 如下这个帖子 http www logicbig com tutorials spring framework spring boot boot serve dynamic
  • 在 C++ 中什么时候首选传递指针而不是引用传递?

    我可以想象一种情况 其中输入参数可以为 NULL 以便首选传递指针而不是传递引用 有人可以添加更多案例吗 在传递的对象实际上将被修改的情况下 有些人更喜欢传递指针 当对象通过引用传递时 它们使用 pass by const referenc
  • 会话过期后如何重定向到登录页面?

    我有三个 JSF 2 0 Web 模块 当会话过期时我需要重定向到登录页面 我已经尝试过使用HttpSessionListener 它正在调用sessionDestroyed 事件方法 但我无法在那里转发 重定向请求 我认为这是因为没有Ht
  • 你能测试一下 mixin 是否存在吗?

    Sass 快速提问 希望如此 你能测试 mixin 是否存在吗 例如 if thumbnail mixin else define mixin 理想情况下我会使用 unless 但这只存在于叉子上 我知道你可以覆盖 mixin 但我想更多的
  • iOS 中的视频可以进行反卷积吗?

    我想拍摄击球手挥动棒球的镜头 但球棒很模糊 视频为 30 fps 通过研究 我发现反卷积似乎是最小化运动模糊的方法 但我不知道是否或如何在我的 iOS 应用程序后处理中实现它 我希望有人能给我指出正确的方向 比如如何在 iOS 中应用反卷积
  • QGraphicsView 和 eventFilter

    这个问题已经困扰我两天多了 所以我想我应该问一下 我在Win7上使用Qt 4 5 3 用VC2008编译 我有 MyGraphicsView 继承 QGraphicsView 和 MyFilter 继承 QObject 类 当我将 MyFi
  • 当 QML 对象不可见时防止 QML 属性绑定?

    我正在开发一个具有大量属性绑定的 QML 应用程序 数百个对象被跟踪并以不同的形式显示 例如 Qt3D QCanvas 当我在应用程序的单独页面上时 x y 位置和相对大小的属性绑定仍在发生 我怎样才能阻止他们 我知道我可以根据属性是否可视
  • 无法构建项目输出组内容文件

    目前 我正在尝试使用 Visual Studio 2010 为我们的 ASP net4 Silverlight Web 应用程序之一创建一个 WebSetup 项目 我根据创建了安装项目this http weblogs asp net s
  • 为什么 getch 不可移植?

    是什么使得 getch 本质上无法作为标准 C 函数包含在内 对于控制台界面来说 它是如此直观和优雅 如果没有它 要求输入单个字符总是会产生误导 因为用户可以输入多个键 更糟糕的是 您经常需要确保在读取控制台输入后清除标准输入 这甚至不是作