简体   繁体   English

为什么此代码打印行而不是单个字符

[英]Why does this code print lines and not single chars

#include <stdio.h>
int main()
{
  int c;
  while((c=getchar())!=EOF)
  putchar(c);
  return 0;
}

In my limited exposure to C,as long as C!=EOF the while condition will get executed which essentially will print c and then wait for the next char and try to examine of that does or does not violate the condition. 在我对C的有限暴露中,只要C!= EOF,就会执行while条件,该条件实际上将打印c,然后等待下一个字符并尝试检查是否违反条件。 Hence for each char we put enter the putchar will execute. 因此,对于我们输入的每个字符,将执行putchar。 However when I ran the executable what seemed to happen was the print statement would work only when I pressed for new line (Enter) and it had a buffer of some sort which would print the whole line in the input. 但是,当我运行可执行文件时,似乎发生的事情是只有当我按下换行键(Enter)时,print语句才能工作,并且它具有某种类型的缓冲区,可以在输入中打印整行。 I fail to see any buffer in the code that will hold the chars until a new line is pressed,so what is being done here ? 我在代码中看不到任何将保留字符的缓冲区,直到按了新行为止,那么这里正在做什么? Where is these chars getting stored until a new line is pressed ? 这些字符存储在哪里,直到按新行?

When reading from the console like this, your program does not actually receive any input at all until you press enter, and then it reads and processes the entire line at once. 当从这样的控制台读取时,您的程序实际上根本没有收到任何输入,除非您按Enter键,然后它会立即读取并处理整行。

Your program has no idea that those characters even exist until you press enter, at which point they are sent to the stdin buffer. 您的程序不知道这些字符甚至在您按Enter之前就存在,然后将它们发送到stdin缓冲区。 From here, your loop will read and print each character (including the new line) until either the buffer is empty (meaning it will wait for more input), or the end of file is reached. 从这里开始,循环将读取并打印每个字符(包括新行),直到缓冲区为空(这意味着它将等待更多输入)或到达文件末尾。

The buffering is happening in the the reading of data and the writing of data. 缓冲发生在读取数据写入数据中。

stdin and stdout , independently can be character , line or fully buffered. stdinstdout可以分别是characterline完全缓冲。

In your common case, both are line buffered. 在通常情况下,两者都是缓冲的。

Input is not given to getchar() until Enter ( '\\n' ) is hit. 按下Enter'\\n' )之前,不会将输入提供给getchar() (Can you back-space input?) and output is not displayed until a '\\n' is printed. (您可以退格输入吗?)直到输出'\\n'后才显示输出。

The getchar() and putchar() functions are part of stdio package, that makes buffered input/output. getchar()putchar()函数是stdio程序包的一部分,该程序包用于缓冲输入/输出。

This means that, despite of the number of characters you actually request (one only in your case) the buffering mechanism makes the characters to wait in the buffer until a whole buffer (or one line, in case stdin comes from a tty device) is filled. 这意味着,尽管您实际请求的字符数(仅在您的情况下为一个),缓冲机制仍使字符在缓冲区中等待,直到整个缓冲区(或一行,以防stdin来自tty设备)为止。填充。

What is happening here is that, on first getchar() a full buffer fill is requested, and filled only partially with the input line you keyed in. After that, all the getchar() calls take individual characters from the buffer, until it is empty again, and at that time, another full buffer is requested. 这里发生的是,在第一个getchar()上,请求完整的缓冲区填充,并且只用您键入的输入行部分填充。之后,所有的getchar()调用都从缓冲区中获取单个字符,直到再次为空,这时,请求另一个满缓冲区。

This is made to make single char processing an efficient way of processing. 这使得单字符处理成为一种有效的处理方式。 That also happens on output. 输出也会发生这种情况。 The putchar() function only fills the buffer, until it is completely full (or, in case your output channel is to a tty device, until you request to output a \\n character) and when it is, the full buffer is output to the file/device. putchar()函数仅填充缓冲区,直到缓冲区完全填满(或者,如果您的输出通道是tty设备,直到您请求输出\\n字符),然后才将缓冲区输出到缓冲区。文件/设备。

Also, the terminal driver in all flavours of unix, works in line mode, what means that until you press the <ENTER> key, you don't get anything sent to the program. 另外,所有版本的unix终端驱动程序都可以在行模式下工作,这意味着,除非按<ENTER>键,否则什么都不会发送到程序。 This will allow you to correct mistakes made on keying, by the use of the erase key (backspace) and/or the kill (Cntrl-U) keys. 这将允许您通过使用擦除键(退格键)和/或取消键(Cntrl-U)来更正键控上的错误。 This is simulated in Windows console applications, so you'll probably need the output device into raw mode before being able to input in a character based way. 这是在Windows控制台应用程序中模拟的,因此您可能需要使输出设备进入原始模式,然后才能以基于字符的方式进行输入。

If you want to make your program to read one character at a time, you need to bypass the buffers of stdio (via setbuf(NULL) function call, or using the read(2) system call to read one character, which can be done with: 如果要使程序一次读取一个字符,则需要绕过stdio的缓冲区(通过setbuf(NULL)函数调用,或使用read(2)系统调用读取一个字符,可以完成此操作)有:

char c;
int res = read(0, &c, 1);
if (res < 0) { /* error */
    ...
} else if (res == 0) { /* EOF in input */
    ...
} else { /* 1, as you requested only one char */
    ... /* one character was read. */
}

) and to put the terminal driver in raw mode (via tcsetattr() and tcgetattr() calls, see termios(4) manual page for details on how to do this) before you do actual reading. ),然后将终端驱动程序置于原始模式(通过tcsetattr()tcgetattr()调用,有关执行此操作的详细信息,请参阅termios(4)手册页),然后再进行实际阅读。 In this case, you must return the terminal state to line mode before terminating the program, or you will run into trouble. 在这种情况下,必须在终止程序之前将终端状态返回到线路模式,否则会遇到麻烦。

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

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