[C++] 파일의 임의 위치 접근하기
이 글은 개인의 학습을 목적으로 정리한 글입니다. 이점 참고하고 읽어주세요;)
C++ 언어를 통해 파일의 데이터를 다룰 때, 파일의 데이터에서 임의의 위치에 접근해서 데이터를 읽거나 수정해야 하는 순간이 있습니다. 이번 포스팅에서는 파일의 임의 위치에 접근하는 방법에 대해 알아보겠습니다.
#include <iostream>
#include <fstream> // 파일 입출력에 사용
#include <string>
#include <cstdlib> // exit에 사용
#include <sstream>
using namespace std;
예제의 헤더는 위와 같습니다. 파일 입출력을 관리하는 <fstream>(file stream)헤더와 예외 상황을 처리하는 exit을 사용하기 위해 <cstdlib>(C Standard Library)를 추가합니다.
int main()
{
const string filename = "my_file.txt";
// 1번 스코프
{
ofstream ofs(filename);
for (char i = 'a'; i < 'z'; ++i)
ofs << i;
}
// 2번 스코프
{
ifstream ifs(filename);
ifs.seekg(5); // 처음부터 5바이트 이동 후 읽음
cout << (char)ifs.get() << endl;
ifs.seekg(5, ios::cur); // 커서로부터 5바이트 이동 후 읽음
cout << (char)ifs.get() << endl;
ifs.seekg(-5, ios::end);
cout << (char)ifs.get() << endl; // 마지막 데이터로부터 5바이트 앞의 값을 읽음
}
}
main 함수는 위와 같습니다. 이번에는 파일 이름을 변수에 저장하고 사용하기 위해 const string 자료형 변수 filename에 이번 예제에서 사용할 파일의 이름인 "my_file.txt"를 저장합니다.
1번 스코프에서는 파일에 값을 저장, 즉 파일에 출력을 하기 위해 ofstream(output file stream) 타입 변수 ofs에 사전에 정의한 filename을 인자로 전달합니다. 그리고 for문을 통해 알파벳 a부터 z까지 차례대로 my_file.txt에 저장합니다.
2번 스코프에서는 이제 파일을 읽기 위해 ifstream(input file stream)타입 변수 ifs를 선언하고 역시 전달 인자로 filename을 줍니다. 그리고 파일의 데이터를 사용자가 지정한 임의의 위치에서부터 읽기 위해 seekg 함수를 사용합니다.
seekg함수의 매개변수로 주는 숫자는 처음부터 몇 바이트를 이동하여 파일을 읽을 것인지를 결정합니다. 예제에서는 5를 매개변수로 주었으니 처음부터 5바이트를 이동한 데이터를 읽습니다. 그리고 get함수를 통해 ifs에 저장된 값이 정말 처음부터 5바이트 떨어진 데이터인지 확인합니다.
그리고 밑에 다시 seekg함수를 사용해서 임의의 위치에 접근하려고 합니다. 이번에는 seekg의 매개변수로 숫자 외에 ios::cur이라는 값을 줬습니다. ios::cur이란 현재 커서의 위치, 그러니까 예제에서는 처음부터 5번째 떨어진 위치로부터 다시 5번째 떨어진 위치의 값을 가져온다는 의미입니다.
프로그램을 실행시켜보니 f와 l이 출력되었습니다.
main 파일의 디렉터리에 가서 my_file.txt 파일을 열어보니 a부터 z까지의 알파벳이 정확하게 저장되어있는 걸 확인할 수 있습니다. 그리고 프로그램의 출력 역시 a로부터 5바이트 떨어진 f와, f로부터 5바이트 떨어진 l을 정확히 출력하고 있는 걸 알 수 있습니다.
{
fstream iofs(filename);
iofs.seekg(5); // 파일 읽기
cout << (char)iofs.get() << endl;
iofs.seekg(5);
iofs.put('A'); // 덮어쓰기
}
그냥 fstream 타입을 사용하면 put을 사용해 임의로 지정한 위치의 데이터를 수정할 수 있습니다.
string str;
getline(ifs, str);
cout << str << endl;
추가적으로, getline 함수를 사용하면 파일 스트림 변수에 저장된 위치부터 파일 나머지까지의 데이터를 string 변수 str에 모두 저장할 수 있습니다. 위와 같이 getline 코드를 작성하고 프로그램을 실행시키면
위와 같이 l이후의 모든 데이터가 str에 저장되어 cout을 통해 출력됨을 볼 수 있습니다.