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

9iraffe님의 프로필 이미지
9iraffe

작성한 질문수

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

18.6 기본적인 파일 입출력

읽기 및 쓰기에 대해 파일 포인터가 하나만 있는 이유가 궁금합니다.

작성

·

469

0

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

int main()
{
	using namespace std;

	// 1. 파일 입출력의 파일 포인터
	// 테스트용 텍스트 파일 생성
	fstream fs{ "test.txt", std::ios::out };
	fs.close();

	fs.open("test.txt");

	fs << "THIS IS FILE STREAM.\n";

	// 읽기 및 쓰기에 대한 현재 파일 포인터의 위치를 콘솔창에 출력
	cout << "읽기 위치: " << fs.tellg() << '\n';		// 예상: 0  (파일의 시작 위치)
	cout << "쓰기 위치: " << fs.tellp() << '\n';		// 예상: 22 (THIS IS FILE STREAM.\n를 쓴 후의 위치) 
	cout << endl;
	// => 그러나 동일한 결과를 출력한다.

	// 2. 문자열 스트림 입출력의 스트림 포인터
	stringstream ss;
	ss << "THIS IS STRING STREAM.\n";

	string str;
	ss >> str;
	
	cout << "str: " << str << '\n';					// THIS
	cout << "읽기 위치: " << ss.tellg() << '\n';		// 예상: 4  (THIS를 읽은 후의 위치)
	cout << "쓰기 위치: " << ss.tellp() << '\n';		// 예상: 23 (THIS IS STRING STREAM.\n 이후의 위치)

	return 0;
}

강의 시청 후에 learncpp.com에서 관련된 챕터를 복습하던 중에 파일 포인터는 읽기 및 쓰기에 대한 파일 포인터가 동일하다는 사실을 알게 되었습니다.

그래서 텍스트 파일을 생성해 임의의 문자열을 파일에 작성하고 tellg()와 tellq()로 확인해봤습니다.

결과는 동일한 위치를 반환했습니다. 읽기를 하지도 않았는데 말이죠.

그런데 일반적으로 생각해보면 입력과 출력에 대해 서로 개별적인 포인터를 가져야할 것 같은데 입출력의 기능을 모두 하는 스트림이 동일한 포인터를 가진다는 게 이해가 안돼서, 이번에는 다른 스트림인 문자열 스트림으로 테스트를 했습니다.

놀랍게도 문자열 스트림은 입출력에 대한 포인터를 독립적으로 보유하는지 tellg()와 tellq()는 서로 다른 위치를 반환했습니다.

구글링으로 답을 찾아보려 했지만 능력의 한계로 찾지 못 했습니다.

왜 입출력 파일 스트림만 동일한 포인터를 가지는 건가요?

단독 언어에 국한된 문제가 아니라 운영체제에 관련된 것일까요?

답변 1

2

안녕하세요 :)

짚어주신 것처럼 tellg와 tellp는 동일한 포인터를 다룹니다.

이는 운영체제가 (문자열 스트림 등과는 달리)

파일의 읽기 위치와 쓰기 위치를 구분하지 않기 때문입니다.

9iraffe님의 프로필 이미지
9iraffe
질문자

안녕하세요. 답변 감사합니다.

추가 질문으로 운영체제가 둘을 구분하지 않는 이유가 무엇인가요?

학부생인데 아직 운영체제를 배우지 않아서 여전히 의문이네요.

안녕하세요, 아래 도서의 내용을 첨부합니다. 

 

이 링크에서도 확인할 수 있습니다.

(Computer Science Illuminated (공)저: Nell B. Dale, John Lewis)

 

(자세히 읽어보지는 않았지만) 아래 내용에 따르면, 특정 내용을 삭제하는 연산에서 유용하게 사용된다고 하네요.

9iraffe님의 프로필 이미지
9iraffe
질문자

친절한 답변 감사드립니다.

첨부된 도서의 페이지를 읽어보았습니다.

해당 페이지는 파일 시스템의 일반적인 연산들에 대해 소개하는 내용인 듯 싶습니다.

그러나, 언급하신 문단은 제 질문에 답이 되는 것 같지는 않네요.

제 생각에, 해당 부분은 파일 내용 삭제(truncating a file)의 유용함을 설명하는 것 같습니다.

(it is sometime useful to "erase" the imformation in a file, 파일의 정보를 지우는게 유용할 때도 있다)

 

제가 궁금한 점은 OS가 파일을 다룰 때 읽기와 쓰기에 대한 파일 포인터를 동일하게 사용하는 이유입니다.

(언급하신 둘을 독립적으로 관리하는 몇몇 운영체제 사례를 제외)

혹여나 제가 잘못 이해했다면 알려주시면 감사드리겠습니다.

우선 저 또한 "파일 읽기/쓰기 포인터는 동일하다, 대부분의 운영체제가 그를 동일하게 간주하기 때문이다" 정도로 알고 있었기 때문에 관련 내용을 찾아본 뒤 말씀드린다는 점 미리 말씀드립니다.

제 생각에는 삭제 연산의 편의성 때문에 읽기/쓰기 포인터를 동일하게 간주하는 것이 맞는 것 같습니다.

삭제 연산은 언제나 마지막으로 읽은 위치 혹은 마지막으로 쓴 위치에서 이루어지기 때문입니다.

그리고 본문 속 It is sometimes useful to "erase" the information in a file. 에서 It이 가리키는 것은 앞 문단의 The current file pointer for an open file을 가리킨다고 봅니다. 

(그리고 바로 뒤에 나와있듯 The current file pointer는 다음으로 read하거나 write하는 곳을 가리킨다고 되어 있으니 파일 읽기/쓰기 포인터는 동일하다는 점도 알 수 있네요)

상세한 질문 덕에 저 또한 많이 알아갑니다, 저도 감사드립니다.

 

9iraffe님의 프로필 이미지
9iraffe

작성한 질문수

질문하기