【问题标题】:Let user type in the middle of string (c/c++)?让用户在字符串中间输入(c/c++)?
【发布时间】:2018-08-03 12:41:05
【问题描述】:

通常在控制台中显示的 c/cpp 字符串只允许用户在其后键入。

有没有简单的方法让用户在输出字符串的中间输入,例如填空:

____先生是老师。

std::cout 可以很方便地打印出来,但是如何让用户用简单的代码直接在空白处输入并阅读呢?例如如果名称很长,将打印的字符向右移动?

【问题讨论】:

  • 没有“C/C++”这样的语言。请选择一个,答案会有所不同。
  • 标准 C++ 没有办法做到这一点。
  • 你真的在看 3 个单独的字符串。第一个字符串是固定的。第二个字符串是用户输入的。第三个字符串在内容上是固定的,但在位置上是固定的。您可以使用 curses 或 ANSI 转义序列来处理实际显示
  • C 和 C++ 之间的一个区别是 C++ 有 std::string 类型,它为您管理内存,您可以查询它的长度。 C 语言只有字符数组,如果数组不是由 nul 字符终止,则会遇到未定义行为。因此,请使用您使用的单一语言编辑您的标签。

标签: c++ c console


【解决方案1】:

您正在寻找控制控制台/终端。您询问的两种语言都没有任何概念——它们都只知道输入和输出的。这是一个简单的抽象,输入和输出是逐个字符,按顺序完成的。输入不必来自键盘,输出不必是屏幕或终端...

控制屏幕内容非常依赖于平台。如果你在 windows 上,windows API 提供a bunch of functions for controlling a console

如果您想做跨平台的事情,请查看curses。有许多平台的实现,例如ncurses(经常在 *nix 系统上使用)和pdcurses(对 Windows 来说非常好),它们都提供相同的接口。

要了解curses 编程,NCURSES Programming HOWTO 是一个好的开始。只需将#include <ncurses.h> 替换为#include <curses.h>,这样您的代码就不会专门​​与ncurses 绑定,而是适用于任何curses 实现。

【讨论】:

    【解决方案2】:

    是的,你绝对可以这样做(我的意思是,你玩过蛇吗?当时所有游戏都在终端上,你的问题比写游戏简单得多)。

    一个技巧是使用\r,这是一个回车。该字符会将您滑回到行首,从而允许您覆盖前一个字符串。这通常用于加载动画,如

    [---]

    [=---]

    [==-]

    [===]

    为了防止在发送数据之前强制用户按回车,我将展示一个 Linux/Mac 解决方案。

    system("/bin/stty raw"); // Get keystrokes immediately, #include <stdlib.h>
    string s;
    char c;
    cout << "Mr _ is the teacher." << flush;
    while( c = getchar() ) { // #include <stdio.h>
        if( c == 3 ) // CTRL+C
            exit(1);
        if( c == 13 ) { // Newline
            cout << endl;
            break;
        }
        if( c == 127 ) { // Backspace
            if( s.size() > 0 )
                s.pop_back();
        } else {
            s += c;
        }
        cout << "\r"; // Reset the cursor
        cout << "Mr " << s << "_ is the teacher.  " << flush; // Spaces to cover invalid backspace character
        cout << "\r"; // Reset the cursor
        cout << "Mr " << s << "_ is the teacher." << flush;
    }
    system("/bin/stty cooked"); // Go back to buffered input
    

    这可以在 Windows 中通过导入#include&lt;conio.h&gt;,然后使用getch() 而不是getchar() 来完成。 (不需要任何 stty 系统命令)

    确保使用特定于平台的#ifdef 来使您的代码具有可移植性!

    【讨论】:

    • 如果你像我一样对它有点强迫症,有一些方法可以隐藏光标。其实我asked那个问题过去了。您也可以研究 Linux 替代方案。
    • 问题在于并非所有控制台或终端都以相同的方式处理 CR(回车)。有些可能会将回车返回到文本行的开头,有些可能会返回到行首并前进到下一行。这应该被测试。此外,控制台或终端仿真器应标准化为 ANSI 或 VT100。
    • 非常旧的 Mac 版本使用 \r 作为换行符。除了不会将光标拉回开头的系统之外,我还没有听说过任何系统(主要争论是\r\n\n 作为换行符,而不是\r 作为回车符),所以我真的不会担心。 /bin/stty raw 更像是 IMO 的依赖项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 2021-08-25
    • 1970-01-01
    • 2019-10-12
    相关资源
    最近更新 更多