简体   繁体   中英

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. However, within the executable, whenever I press "enter", all my input is sent out, and thus also printed on the next line as 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? I am currently working in the Linux MATE terminal, if that is an influencing factor.

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. 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. However, it is advisable to first record the old value using tcgetattr and restore it afterwards. However, when your input is coming from a terminal you will not see an EOF (hence I added the q option to quit). 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).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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