인프런 커뮤니티 질문&답변

저스트두잇하는중님의 프로필 이미지
저스트두잇하는중

작성한 질문수

홍정모의 따라하며 배우는 C언어

13.1 파일 입출력의 작동 원리

13.1 파일 입출력의 작동원리 파일스트림

작성

·

434

1

파일 스트림도 버퍼를 사용하는 스트림이라는 말씀이신가요?

답변 1

1

안녕하세요, 답변 도우미 Soobak 입니다.

네, 맞습니다.
C++ 에서 파일 스트림( ifstream, ofstream , fstream 등 )은 내부적으로 버퍼를 사용합니다.

파일 스트림 클래스들은 내부적으로 버퍼를 사용하여 데이터를 임시로 저장하며,
버퍼가 가득 찼을 때(혹은 flush 될 때) 한 번에 파일로 쓰거나, 파일에서 한 번에 버퍼로 읽어들입니다.

 

int main()
{
	int ch;
	FILE* fr;

	fr = fopen("input.txt", "r");
	while ((ch = fgetc(fr)) != EOF)
		fputc(ch, stdout);

	fclose(fr);

	return 0;
}

이 코드에서

input.txt에 있는 텍스트들을 버퍼에 임시저장하고 한글짜씩 ch에 빼넣는게 맞나요???

안녕하세요, 답변 도우미 Soobak 입니다.

네, 옳게 이해하신 것 같습니다.
조금 더 부연설명을 드려보자면 다음과 같습니다.

환경과 시스템에 따라서 다를 수 있지만,
파일에서 데이터를 조금씩 여러번 읽는 것 보다, 한 번에 큰 덩어리로 읽어 버퍼에 저장한 다음 필요할 때 마다 그 버퍼에서 문자를 가져오는 방식이 더 효율적이므로, 이러한 방식으로 fgetc 함수가 동작합니다.

이는 효율성을 높이기 위함이며, 일반적으로 버퍼가 '큰 덩어리'로 읽어들이는 크기 역시 환경과 시스템에 따라서 다릅니다. (일반적으로는 몇 kb ~ 몇십 kb 라고 합니다.)
만약, 버퍼가 비어 있을 때는 다시 실제 파일에서 읽기를 수행합니다.

또한, 다음과 같이 명시적으로 지정된 크기만큼 읽을 문자의 수를 설정하여 버퍼로 사용할 수도 있습니다.

char buffer[1024];
fgets(buffer, 1024, fr);


결론적으로, 코드 상의 ch 에 저장되는 것은 한 글자이지만, 환경과 시스템에 따라서, 내부적으로 파일 입/출력 함수는 한 번에 더 큰 양의 데이터를 버퍼에 저장합니다.

저 좀 헷갈리는 부분이 있는데 앞에 강의들에서 버퍼를 배울때 만약 int c = getchar(); 에서 콘솔창에 yes를 입력하면 y,e,s,'\n'까지 네글자가 버퍼에 들어가고 int c에 y값이 들어가면서 버퍼에서 y가 없어지고 e,s,'\n'이 남아있다고 이해를 했었는데

버퍼에서 없어지는게 아니라 y도 남아있고 그냥 읽어들일 위치가 다음 글자로 넘어가는 건가요???

 

안녕하세요, 답변 도우미 Soobak 입니다.

네, 맞습니다.

질문하신 부분에 대해 좀 더 명확하게 설명드리겠습니다.

getchar() 함수는 버퍼에 있는 데이터 중 맨 앞의 문자를 가져옵니다.
만약, "yes\n" 를 입력했을 때, 처음 getchar() 호출로 'y'를 가져오면, 버퍼에서는 'e', 's', '\n' 이 남게 됩니다. 그리고 'y'는 변수 c에 저장됩니다.

그러나 실제 내부적으로 버퍼에서 'y' 가 사라진 것은 아닙니다.
버퍼는 그대로 남아 있으며, 'y' 다음의 'e' 의 위치를 가리키는 '포인터'나 '인덱스'가 이동한 것이기 때문에, 마치 'y' 가 사라진 것 같이 보이는 것입니다.

요약하자면, 버퍼에서 데이터가 '사라진다'는 표현 대신 '읽은 데이터의 위치를 다음 위치로 옮긴다'라는 개념으로 이해하시는 것이 적절할 것 같습니다. 실제로 데이터가 버퍼에서 제거되는 것이 아니라, 다음에 어떤 데이터를 읽을지 결정하는 포인터나 인덱스의 위치가 변경되는 것이기 때문입니다.

정말 감사합니다

저스트두잇하는중님의 프로필 이미지
저스트두잇하는중

작성한 질문수

질문하기