Home > Article > Backend Development > How to clear the input buffer using C language? There are many methods worth learning from
There are several basic input functions in the C language:
<span style="color:#008000;">//获取字符系列</span><br>
int fgetc(FILE *stream);
int getc(FILE *stream);
int getchar(void);
//获取行系列
char *fgets(char * restrict s, int n, FILE * restrict stream);
char *gets(char *s);//可能导致溢出,用fgets代替之。
//格式化输入系列
int fscanf(FILE * restrict stream, const char * restrict format, …);
int scanf(const char * restrict format, …);
int sscanf(const char * restrict str, const char * restrict format, …);
Here we only discuss the use of input functions in the case of standard input (stdin). Looking at the above input functions, <br>
obtains the first three functions fgetc, getc, and getchar of the character series . Taking getchar as an example, when the stdin buffer is empty, it will wait for input until the function returns when the carriage return and line feed occur. If the stdin buffer is not empty, getchar returns directly. When getchar returns, it takes a character from the buffer, converts it to an int, and returns this int value.
##Source code of FILE structure in MINGW 4.4.3:
_iobuf
{
char* _ptr;//指向当前缓冲区读取位置
int _cnt;//缓冲区中剩余数据长度
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;The implementation of each compiler may be different. Here, the character series function is only used to _ptr and _cnt.
<br>
Getchar() implementation in MINGW 4.4.3:
__CRT_INLINE int __cdecl __MINGW_NOTHROW getchar (void)
{
return (--stdin->_cnt >= 0)
? (int) (unsigned char) *stdin->_ptr++
: _filbuf (stdin);
}stdin is the FILE pointer type. In MINGW 4.4.3, getc() and getchar() is implemented as an inline function, and fgetc() is implemented as a function. By the way, support for inline functions has been added to the C99 standard.
Get fgets and gets of line series . Because gets cannot determine the buffer size, it often leads to overflow. The gets function is not recommended or discussed here. For the fgets function, fgets returns every time you press Enter. When fgets returns successfully, the data in the input buffer will be copied to the space pointed to by the first parameter together with the newline character '\n'. If the input data exceeds the buffer length, fgets will intercept the data to the first n-1 (n is the second parameter of fgets, which is the length of the space pointed to by the first parameter), and then add '\n' at the end. Therefore fgets is safe. Usually fgets(buf, BUF_LEN, stdin); is used instead of gets(buf);.
In the formatted input series, fscanf is difficult to use when formatting input from a file stream. The most commonly used one is scanf. The formatted input series functions discard the whitespace characters (spaces, tabs, newline character) until a non-whitespace character is encountered, and then attempts to parse the non-whitespace character and subsequent characters according to the format parameters. This series of functions returns the number of variables successfully parsed and assigned. If it encounters the end of file or an error, it returns EOF.
setbuf and setvbuf, which are declared as follows:
setbuf(FILE * restrict stream, * restrict buf);
int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size);
setvbuf The mode parameters of are:
stdio,stdout
stderr
setbuf(stream, buf); in:
BUFSIZ: Equivalent to (void)setvbuf(stream, buf, _IOFBF, BUFSIZ);
BUFSIZ macro is defined in stdio.h.
I would also like to mention theclassic mistake of the legendary setbuf, which is mentioned in "C Traps and Defects":
main()
{
int c;
char buf[BUFSIZ];
<br>
setbuf(stdout,buf);
while((c = getchar()) != EOF)
putchar(c);
<br>
return 0;
The problem is this: The C runtime library must perform cleanup work before the program returns control to the operating system, part of which is to refresh the output buffer, but at this time the main function has finished running, and the buf buffer scope is in main In the function, the buf character array has been released at this time, causing the output to be strange and garbled.
Solution: You can set buf to static, or a global variable, or call malloc to dynamically apply for memory.
==================Separating line=================Come on Take a look at several popular buffer flushing methods:}
If stream points to an output stream or an update stream in which the most recent
operation was not input, the fflush function causes any unwritten data for that stream
to be delivered to the host environment to be written to the file; otherwise, the behavior is
It can be seen that
fflush does not define the behavior of the input stream as a parameter. But from the definition of fflush on MSDN: undefined.
If the file associated with stream is open for output, fflush writes to that file the
contents of the buffer associated with the stream. If the stream is open for input,
由前面对setbuf函数的介绍,可以得知,setbuf(stdin, NULL);是使stdin输入流由默认缓冲区转为无缓冲区。都没有缓冲区了,当然缓冲区数据残留问题会解决。但这并不是我们想要的。
scanf("%*[^\n]");式(《C语言程序设计 现代方法 第二版》中提到)
这里用到了scanf格式化符中的“*”,即赋值屏蔽;“%[^集合]”,匹配不在集合中的任意字符序列。这也带来个问题,缓冲区中的换行符’\n’会留下来,需要额外操作来单独丢弃换行符。
经典式
c;
while((c = getchar()) != '\n' && c != EOF);
由代码知,不停地使用getchar()获取缓冲区中字符,直到获取的字符c是换行符’\n’或者是文件结尾符EOF为止。这个方法可以完美清除输入缓冲区,并且具备可移植性。<br>
相关文章:
如何批量清理系统临时文件(语言:C#、 C/C++、 php 、python 、java )
相关视频:
The above is the detailed content of How to clear the input buffer using C language? There are many methods worth learning from. For more information, please follow other related articles on the PHP Chinese website!