简体   繁体   English

你如何防止输入在终端的新行上发送?

[英]How do you prevent input from being sent on new line in terminal?

I am trying to learn how input/output works, and was curious about something regarding this basic code from a textbook:我正在尝试了解输入/输出的工作原理,并对教科书中的基本代码感到好奇:

#include <stdio.h>
/* copy input to output; 1st version */

int main()
{
int c;

c = getchar();
while (c != EOF) {
    putchar(c);
    c = getchar();
}
}

After I use gcc to turn this code into an executable, it runs completely fine.在我使用 gcc 将此代码转换为可执行文件后,它运行完全正常。 However, within the executable, whenever I press "enter", all my input is sent out, and thus also printed on the next line as output.但是,在可执行文件中,每当我按下“enter”时,我的所有输入都会被发送出去,因此也会在下一行打印为 output。 How could I set things up so that so I can get the new line, '\n', that I want out of enter, without signalling that I want to send my input?我如何进行设置,以便我可以得到我想要退出输入的新行 '\n',而不发出我想要发送输入的信号? I am currently working in the Linux MATE terminal, if that is an influencing factor.我目前在 Linux MATE 终端工作,如果这是一个影响因素。

When you run this command in the terminal (without redirection), typically, the input you are typing is echoed by the terminal and only sent to your program after you press enter.当您在终端中运行此命令(无重定向)时,通常,您输入的输入会由终端回显,并且仅在您按 Enter 后才会发送到您的程序。 Then the loop is will start reading each character you typed and display it.然后循环将开始读取您键入的每个字符并显示它。 Afterwards, it again waits for input which the terminal only sends after you press enter.之后,它再次等待终端仅在您按下回车后才发送的输入。

Try redirecting your input from a file and see the difference.尝试从文件重定向您的输入并查看差异。

prompt$ ./yourprogram < somefile

If you want to be able to read each character immediately as typed by the user, you need to disable canonical mode (line buffering) in your program using the tcsetattr function.如果您希望能够立即读取用户键入的每个字符,则需要使用 tcsetattr function 在程序中禁用规范模式(行缓冲)。 However, it is advisable to first record the old value using tcgetattr and restore it afterwards.但是,建议先使用 tcgetattr 记录旧值,然后再将其恢复。 However, when your input is coming from a terminal you will not see an EOF (hence I added the q option to quit).但是,当您的输入来自终端时,您将看不到 EOF(因此我添加了 q 选项来退出)。 If this is what you are looking for, you may also want to disable echoing the characters (commented line).如果这是您要查找的内容,您可能还希望禁用回显字符(注释行)。

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int main() {
  struct termios old_tio, new_tio;
  tcgetattr(STDIN_FILENO, &old_tio);
  new_tio=old_tio;
  new_tio.c_lflag &=(~ICANON);
  /* new_tio.c_lflag &=(~ECHO); */
  tcsetattr(STDIN_FILENO, TCSANOW, &new_tio);

  int c;
  c = getchar();
  while (c != EOF) {
    putchar(c);
    c = getchar();
    if (c=='q') break;
  }

  tcsetattr(STDIN_FILENO, TCSANOW, &old_tio);
}

Standard input is buffered in the sense that the program does not receive the input until you send a newline or until you send EOF ( Ctrl D in some terminal emulators).标准输入是缓冲的,因为在您发送换行符或发送 EOF (某些终端仿真器中的Ctrl D )之前程序不会接收输入。

If you need to handle input as it arrives (key strokes), you need to use something else (ie outside of the standard).如果您需要在输入到达时处理(击键),您需要使用其他东西(即标准之外)。 For instance, the ncurses library is a popular solution for Linux CLI applications.例如,ncurses 库是 Linux CLI 应用程序的流行解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM