>  기사  >  백엔드 개발  >  C 언어를 사용하여 입력 버퍼를 지우는 방법은 무엇입니까? 배울 만한 가치가 있는 방법이 많이 있습니다.

C 언어를 사용하여 입력 버퍼를 지우는 방법은 무엇입니까? 배울 만한 가치가 있는 방법이 많이 있습니다.

php是最好的语言
php是最好的语言원래의
2018-08-01 11:46:592982검색

C 언어에는 몇 가지 기본 입력 함수가 있습니다.

<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, …);

여기에서는 표준 입력(stdin)의 경우 입력 함수 사용에 대해서만 설명합니다. 위의 입력 함수를 보면 <br>

  • 은 문자 계열 의 처음 세 함수 fgetc, getc 및 getchar를 가져옵니다. getchar를 예로 들면, stdin 버퍼가 비어 있으면 캐리지 리턴 및 줄 바꿈이 발생할 때 함수가 반환될 때까지 입력을 기다립니다. stdin 버퍼가 비어 있지 않으면 getchar가 직접 반환됩니다. getchar가 반환되면 버퍼에서 문자를 가져와 int로 변환하고 이 int 값을 반환합니다.

MINGW 4.4.3 FILE 구조 소스 코드:

  _iobuf
{
	char*	_ptr;//指向当前缓冲区读取位置
	int	_cnt;//缓冲区中剩余数据长度
	char*	_base;
	int	_flag;
	int	_file;
	int	_charbuf;
	int	_bufsiz;
	char*	_tmpfname;
} FILE;
__CRT_INLINE int __cdecl __MINGW_NOTHROW getchar (void)
{
  return (--stdin->_cnt >= 0)
    ?  (int) (unsigned char) *stdin->_ptr++

여기서는 _ptr 및 _cnt만 사용하여 문자 계열 함수를 얻습니다. <br>

MINGW 4.4.3의 Getchar() 구현:

    : _filbuf (stdin);
}
 setbuf(FILE * restrict stream,  * restrict buf);
int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size);
 main()
{

여기서 stdin은 MINGW 4.4.3에서 getc() 및 getchar()가 인라인 함수로 구현되고 fgetc()는 다음과 같습니다. 함수로 구현되었습니다. 그런데 C99 표준에는 인라인 함수에 대한 지원이 추가되었습니다.

  • 행 계열의 fget 및 가져오기 가져오기는 버퍼 크기를 결정할 수 없기 때문에 종종 오버플로가 발생하므로 여기서는 가져오기 기능을 권장하거나 논의하지 않습니다. fgets 함수의 경우 Enter를 누를 때마다 fgets가 반환됩니다. fgets가 성공적으로 반환되면 입력 버퍼의 데이터와 개행 문자 'n'이 첫 번째 매개변수가 가리키는 공간에 복사됩니다. 입력 데이터가 버퍼 길이를 초과하면 fgets는 데이터를 첫 번째 n-1(n은 fgets의 두 번째 매개변수, 첫 번째 매개변수가 가리키는 공간의 길이)까지 가로채서 'n'을 추가합니다. 마지막에. 그러므로 fgets는 안전합니다. 일반적으로 gets(buf); 대신 fgets(buf, BUF_LEN, stdin);가 사용됩니다.

  • 형식화된 입력 시리즈에서 파일 스트림의 입력 형식을 지정할 때 fscanf를 사용하기가 매우 어렵습니다. 가장 일반적으로 사용되는 것은 scanf입니다. 형식이 지정된 입력 시리즈 함수는 입력 데이터 앞의 공백 문자(공백, 탭, 줄 바꿈)를 삭제합니다(함수에 따라 표준 입력 또는 sscanf와 같은 문자열 입력일 수 있음). 공백이 아닌 문자가 발견될 때까지 형식 매개변수에 따라 공백이 아닌 문자와 후속 문자를 구문 분석하려고 시도합니다. 이 일련의 함수는 성공적으로 구문 분석되고 할당된 변수의 수를 반환합니다. 파일 끝이나 오류가 발생하면 EOF를 반환합니다.

==================줄 구분===================

버퍼의 경우, 두 개의 버퍼 설정 함수 setbufsetvbuf는 다음과 같이 선언됩니다.

    int c;
    char buf[BUFSIZ];

setvbuf의 모드 매개변수는 다음과 같습니다.

  • _IOFBF(전체 버퍼): 버퍼가 비어 있을 때 데이터를 읽습니다. ; 버퍼가 가득 차면 스트림에 데이터를 씁니다.

  • _IOLBF(행 버퍼): 한 번에 스트림에서 한 행의 데이터를 읽거나 스트림에 데이터를 씁니다. 예: stdio, stdout

  • _IONBF(버퍼되지 않음): 스트림에서 직접 데이터를 읽거나 버퍼 없이 스트림에 직접 데이터를 씁니다. 예: stderr

setbuf(stream, buf); in:

  • buf == NULL: (void)setvbuf(stream, NULL, _IONBF, 0);

  • buf는 길이가 BUFSIZ인 버퍼를 가리킵니다. (void)setvbuf(stream, buf, _IOFBF, BUFSIZ);

참고: BUFSIZ 매크로는 stdio.h에 정의되어 있습니다.

여기서 "C Traps and Defects"에서 언급된 전설적인 setbuf고전적인 오류에 대해서도 언급하고 싶습니다.

<br>
    setbuf(stdout,buf);
    while((c = getchar()) != EOF)
        putchar(c);
    <br>
    return 0;
}
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

문제는 다음과 같습니다. 는 운영 체제 런타임 라이브러리는 정리 작업을 수행해야 하며 그 중 일부는 출력 버퍼를 새로 고치는 것입니다. 그러나 이때 주 함수의 실행이 완료되고 buf 버퍼 범위가 주 함수에 있으며 buf 문자 배열이 해제되었습니다. 이번에는 이상하고 왜곡된 출력이 발생했습니다.

해결책: buf를 정적 변수 또는 전역 변수로 설정하거나, malloc을 호출하여 동적으로 메모리를 적용할 수 있습니다.

=================줄 구분===================

몇 가지 인기 있는 버퍼를 살펴보겠습니다. 삭제 방법:

  • fflush(stdin); Formula

C99 표준 문서에서:

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,
fflush clears the contents of the buffer.
입력 스트림에 대한

fflush의 동작이 매개변수로 정의되지 않았음을 볼 수 있습니다. 그러나 MSDN의 fflush 정의:

 c;
while((c = getchar()) != '\n' && c != EOF);
rrreee

fflush(stdin)가 VC에서 여전히 유효하다는 것을 알 수 있습니다! 각 컴파일러는 fflush의 정의되지 않은 동작을 다르게 구현하므로 fflush(stdin)를 사용하여 입력 버퍼를 새로 고치는 것은 권장되지 않습니다.

  • setbuf(stdin, NULL);Formula

由前面对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 )

相关视频:

C 语言教程

위 내용은 C 언어를 사용하여 입력 버퍼를 지우는 방법은 무엇입니까? 배울 만한 가치가 있는 방법이 많이 있습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.