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

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

php是最好的语言
풀어 주다: 2018-08-01 11:46:59
원래의
3085명이 탐색했습니다.

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿