在 C 中预填充标准输入

pre-fill stdin in C

我的程序应该让用户编辑文件的一行。用户编辑该行并按回车键将其发回。因此我想打印即将被编辑的当前行,但是在标准输入而不是标准输出上打印它。 我不知道如何解决的唯一问题是如何预填充标准输入。我已经试过了:

char cprefill[] = {"You may edit this line"};
char cbuffer[100];
fprintf(stdin, cprefill);
fgets(cbuffer, 100, stdin);

这似乎是最简单的解决方案,但可能过于简单而无法工作。 fprintf 不会向标准输入输出任何内容。正确的做法是什么?

编辑:

这是它应该的样子。请注意可以移动的光标。

首先你需要 libreadline developer 包。 (如果 libreadline 在您的系统上尚不可用,您可能还需要它)

在 Debian/Ubuntu 上是 apt install libreadline-dev(加上 libreadline6 如果您还需要二进制文件 - 6 在您的平台上可能不同)

然后你可以添加一个历史到readline,像这样

#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>    

...

char cprefill[] = {"You may edit this line"};

add_history(cprefill);

char *buf = readline("Line: ");

printf("Edited line is %s\n", buf);

// free the line allocated by readline
free(buf);

系统会提示用户 "Line: ",并且必须执行 向上箭头 以获取和编辑历史记录,即 cprefill 行。

请注意,您必须 compile/link 和 -lreadline

readline 打印作为参数给出的提示,然后等待用户交互,允许行编辑,以及加载历史记录中存储的行的箭头。

然后必须释放 readline 返回的 char *(因为该函数使用 malloc() 分配缓冲区)。

C 语言没有终端和行版的概念,因此无法以可移植的方式完成。您可以依靠像 [n]curses 这样的库来获得几乎可移植的解决方案,或者如果您只需要在一个 OS 上使用低级 OS 原语。

例如 Windows,您可以在阅读之前通过模拟按键输入适当的 window(例如通过发送 WM_CHAR 消息)来提供输入缓冲区,但是将是高度不可移植的 - 最后不再是 C 而是 Windows 解决方案...

您可以使用 GNU Readline。它在开始时调用 rl_startup_hook 指向的函数,在这里我们使用 rl_insert_text 将我们的文本放入行缓冲区。

#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

int prefill(void)
{
    rl_insert_text("You may edit this line");

    return 0;
}

int main(void)
{
    char *cbuffer;

    puts("Please edit the following line");
    rl_startup_hook = prefill;
    if ((cbuffer = readline(NULL)) == NULL) /* if the user sends EOF, readline will return NULL */
        return 1;
    printf("You entered: %s\n", cbuffer);
    free(cbuffer);

    return 0;
}

有关详细信息,请参阅 GNU Readline manual