scanf() inner buffer vs read() inner buffe

먼저, read() 의 버퍼 read(fd, buf, nbytes) 는 커널에 진입해서 파일 디스크립터(fd)가 가리키는 커널 내부 객체(inode, tty, socket 등)의 커널 버퍼 캐시에서 데이터를 꺼내 유저 공간의 buf에 직접 복사를 한다.

즉, read는 커널 ↔ 사용자 공간 사이의 경계에서 데이터를 옮기는 API ( 시스템콜 ) 이다. 커널 측 버퍼는 장치 드라이버나 VFS 레이어에 의해 유지되며, 프로그램이 직접 접근할 수 없다.

scanf() 의 버퍼 scanf는 내부에서 → fscanf(stdin, ...)이고, 내부적으로는 FILE *stdin을 사용한다. FILE 객체(glibc의 _IO_FILE)는 유저 공간에 있는 inner buffer를 가지고 있음. 흐름:

처음 요청할 때 scanf가 내부 getc 류를 호출.

  1. 만약 stdin의 내부 버퍼가 비어 있다면 → 라이브러리가 read()를 호출해 대량(예: BUFSIZ = 8192바이트) 을 한 번에 가져옴
  2. 그 후 scanf는 내부 포인터(_IO_read_ptr.._IO_read_end) 를 움직이면서, 필요한 만큼만 파싱해서 메모리에 저장 • 즉, scanf는 read()를 자잘하게 여러 번 호출하지 않고, 자기만의 중간 버퍼에서 효율적으로 처리한다. • 남은 데이터는 유저 공간의 FILE 버퍼에 그대로 남아, 다음 호출 때 재사용

어떻게 보면 read 와 같은 시스템콜을 최대한 줄일려는 노력이기도 하다.

구분read()scanf() (FILE 기반)
위치커널 공간 (OS 레벨)유저 공간 (C 라이브러리 내부)
누가 관리?운영체제 커널 (VFS, 드라이버)C 표준 라이브러리 (stdio)
데이터 단위호출 시 지정한 크기만큼내부 버퍼 단위(보통 BUFSIZ)로 읽고 포인터 이동
시스템 콜호출할 때마다 발생버퍼가 빌 때만 발생
성능작은 크기로 반복 호출 시 느림버퍼링 덕분에 호출 횟수 줄어 빠름
기능바이트 단순 복사공백 스킵, 숫자 파싱 등 고수준 처리

참고로 FILE 기반 버퍼의 주요위치에 대해

운영체제 커널 (VFS, 드라이버) 여기서 좀더 자세히 들어가보자면,