clrscr() 不工作,getch() 工作。为什么?

2024-04-28

我正在做一个小C请求密钥并执行 switch 语句中的某些代码的程序。

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

int main(int argc, char const *argv[]){
    /* code */
    printf("Hello, press a, b or c to continue");
    char key = getch();
    switch (key){
    case  'a':
        clrscr();
        //some code
        break;
    case  'b':
        //many lines of code
        break;
    case  'c':
        clrscr();
        //many lines of code
        break;
    default:
        printf("Ok saliendo\n");
        break;
    }
    printf("bye");
}

getch()工作正常,但是clrscr()不是,即使我包括在内<conio.h>.

Why?


conio.h https://en.wikipedia.org/wiki/Conio.h死了!

一些背景:conio.h定义了一个 API,该 API 曾被创建用于控制 IBM PC 的(文本!)屏幕。它最初只是 MS-DOS 函数的包装器,因此您不必编写自己的程序集来创建int 21h打电话给他们。确切的APIconio.h从未标准化,并且因实施而异。

我假设您使用的是针对 Windows 的编译器,这些编译器通常仍提供一些变体conio.h。但正如您所看到的,无法保证什么是真正可用的并且可以按您的预期工作。

如今,你甚至不得不问什么是屏幕?您的内容控制台窗口?但是,如果您的控制终端是例如,该怎么办?远程 shell(telnet、ssh...)?甚至不同控制台窗口实现在功能和控制方式上会有所不同。 C只知道输入和输出streams,他们将使用任何类型的终端/控制台,因为他们对screen,只是字符的输入和输出。

为了实际控制“屏幕”,Windows 提供了控制台API https://learn.microsoft.com/en-us/windows/console/console-reference,您可以直接使用它,但是您的程序仅“硬连线”到 Windows。大多数其他控制台/终端都理解某种转义码,常常是ANSI 转义码 https://en.wikipedia.org/wiki/ANSI_escape_code。从 Windows 10 开始的 Windows 也提供了对它们的可选支持。但是有各种各样的终端可以理解不同的代码(及其不同的子集),因此直接使用它们也不是一个好主意。


如今,事实上的标准用于控制终端/控制台的是诅咒API https://en.wikipedia.org/wiki/Curses_(programming_library)它起源于 BSD Unix,但存在多种系统和控制台的实现。最为显着地,ncurses https://www.gnu.org/software/ncurses/可用于many系统,甚至包括 Windows,但对于 Windows,您还可以pdcurses https://pdcurses.sourceforge.io/。甚至还有一个扩展程序 https://www.projectpluto.com/win32a.htm对于实现其的 Windowsown控制台窗口,因此您可以使用本机 Windows 控制台所没有的功能。当然,您不需要这个来只是“清除屏幕”并从键盘读取一些输入。

当你使用curses,你必须使用所有控制台/终端输入和输出curses函数(你不能使用stdio功能类似于printf()为了那个原因)。这是一个小示例程序:

#include <curses.h>
// don't include `ncurses.h` here, so this program works with 
// different curses implementations

#include <ctype.h>  // for `isalnum()`

int main(void)
{
    initscr();  // initialize curses, this also "clears" the screen
    cbreak();   // among other things, disable buffering
    noecho();   // disable "echo" of characters from input

    addstr("Hello, press a key!\n");  // output a constant string, like puts/fputs
    refresh();  // output might be buffered, this forces copy to "screen"

    int c;
    do
    {
        c = getch();        // read a single character from keyboard
    } while (!isalnum(c));  // ignore any input that's not alphanumeric

    printw("You entered '%c'.\n", c);  // formatted output, like printf

    addstr("press key to exit.\n");
    refresh();
    c = getch();

    endwin();   // exit curses
}

您可以编译它,例如像这样使用 gccncurses:

gcc -std=c11 -Wall -Wextra -pedantic -ocursestest cursestest.c -lncurses

Or with pdcurses:

gcc -std=c11 -Wall -Wextra -pedantic -ocursestest cursestest.c -lpdcurses

要了解更多信息curses,我推荐NCURSES 编程指南 http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/.

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

clrscr() 不工作,getch() 工作。为什么? 的相关文章

  • 数据模板绑定垃圾邮件输出窗口出现错误:找不到管理 FrameworkElemen

    我有问题 System Windows Data 错误 2 找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement BindingExpression 无路径 数据项 空 目标元素是 So
  • ASP.Net Core 内容配置附件/内联

    我正在从 WebAPI 控制器返回一个文件 Content Disposition 标头值自动设置为 附件 例如 处置 附件 文件名 30956 pdf 文件名 UTF 8 30956 pdf 当它设置为附件时 浏览器将要求保存文件而不是打
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • std::forward_as_tuple 将参数传递给 2 个构造函数

    我想传递多个参数以便在函数内构造两个对象 以同样的方式std pair
  • 如何从文本文件读取整数到数组

    这就是我想做的 我对此有些不满 但我希望你能容忍我 这对我来说是一个非常新的概念 1 在我的程序中 我希望创建一个包含 50 个整数的数组来保存来自文件的数据 我的程序必须获取用户的文档文件夹的路径 2 文件的名称为 grades txt
  • 检查 RoutedEvent 是否有任何处理程序

    我有一个自定义 Button 类 当单击它时 打开特定窗口 它总是执行相同的操作 我添加了一个可以在按钮的 XAML 中分配的 Click 事件 就像常规按钮一样 当它被单击时 我想执行 Click 事件处理程序 如果已分配 否则我想执行默
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 如何通过 JsonConvert.DeserializeObject 在动态 JSON 中使用 null 条件运算符

    我正在使用 Newtonsoft 反序列化已知的 JSON 对象并从中检索一些值 如果存在 关键在于对象结构可能会不断变化 因此我使用动态来遍历结构并检索值 由于对象结构不断变化 我使用 null 条件运算符来遍历 JSON 代码看起来像这
  • 使用restsharp序列化对象并将其传递给WebApi而不是序列化列表

    我有一个看起来像的视图模型 public class StoreItemViewModel public Guid ItemId get set public List
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • C++ Streambuf 方法可以抛出异常吗?

    我正在尝试找到一种方法来获取读取或写入流的字符数 即使存在错误并且读 写结束时间较短 该方法也是可靠的 我正在做这样的事情 return stream rdbuf gt sputn buffer buffer size 但如果streamb
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐