Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 파일 입출력: 클래스 객체를 파일에 읽고 쓰는 방법

개요

C++의 iostream 표준 라이브러리는 표준 입력 스트림으로부터 데이터를 받아들이는 cin과, 표준 출력 스트림에 결과를 내보내는 cout이라는 두 가지 핵심 메서드를 제공합니다. 이 글에서는 파일로부터 데이터를 읽어 클래스 객체에 저장하는 방법과, 클래스 객체의 데이터를 파일에 기록하는 방법을 자세히 살펴보겠습니다.

파일 입출력을 위해서는 C++의 또 다른 표준 라이브러리인 <fstream>이 필요합니다. fstream의 세 가지 주요 데이터 타입은 다음과 같습니다.

  • ifstream — 입력 파일 스트림을 나타내며, 파일로부터 정보를 읽어옵니다.
  • ofstream — 출력 파일 스트림을 나타내며, 파일에 정보를 기록합니다.
  • fstream — 일반 파일 스트림을 나타내며, 읽기와 쓰기 두 가지 기능을 모두 수행할 수 있습니다.

클래스 객체 생성하기

여기서는 이름(Name), 사원 번호(Employee_ID), 급여(Salary)를 public 데이터 멤버로 가지는 Employee 클래스를 예제로 사용하겠습니다.

class Employee {
    public:
        char Name[];
        long Employee_ID;
        int Salary;
};
Employee Emp_1;
Emp_1.Name="Jhonson";
Emp_1.Employee_ID=212020;
Emp_1.Salary=11000;

파일 객체 생성하기

문법

fstream/ofstream/ifstream object_name;
void open(const char *filename, ios::openmode);
ofstream file1;
file1.open( "Employee.txt", ios::app );
  • 위 코드에서 file1은 Employee.txt 파일을 추가 모드(ios::app, 새로운 내용이 파일 끝에 덧붙여짐)로 열 때 사용되는 객체입니다. file1의 타입은 ofstream이므로 Employee.txt 파일에 데이터를 쓸 수 있습니다.
ifstream file2;
file2.open( "Employee.txt", ios::in );
  • 반면 file2는 Employee.txt 파일을 입력 모드(ios::in)로 열어 내용을 읽을 때 사용되는 객체입니다. file2의 타입은 ifstream이므로 Employee.txt에서 데이터를 읽기만 할 수 있습니다.

클래스 객체 쓰기와 읽기

file1.write( (char*)&Emp_1, sizeof(Emp1) );
  • write 함수를 호출하면 클래스 객체 Emp_1에 담긴 데이터가 Employee.txt 파일에 기록됩니다. (char*)&Emp_1은 객체의 시작 주소를 가리키며, sizeof(Emp_1)은 파일에 복사될 바이트 수를 계산합니다.
file2.read( (char*)&Emp_1, sizeof(Emp1) );
  • read 함수를 호출하면 Employee.txt 파일로부터 데이터를 읽어 클래스 객체 Emp_1에 저장합니다. 마찬가지로 (char*)&Emp_1은 객체의 시작 주소를 가리키고, sizeof(Emp_1)은 파일에서 읽어올 바이트 수를 계산합니다.

파일 닫기

file1.close();
file2.close();

close() 함수를 호출하여 파일의 입력 스트림과 출력 스트림을 닫습니다. 파일 작업이 끝나면 반드시 스트림을 닫아 시스템 리소스 누수를 방지하는 것이 좋습니다.

전체 예제 코드

#include <iostream>
#include <fstream>
using namespace std;

// 속성을 정의하는 클래스
class Employee {
public:
    string Name;
    int Employee_ID;
    int Salary;
};

int main(){
    Employee Emp_1;
    Emp_1.Name="John";
    Emp_1.Employee_ID=2121;
    Emp_1.Salary=11000;
    // 이 데이터를 Employee.txt에 기록
    ofstream file1;
    file1.open("Employee.txt", ios::app);
    file1.write((char*)&Emp_1,sizeof(Emp_1));
    file1.close();
    // Employee.txt에서 데이터 읽기
    ifstream file2;
    file2.open("Employee.txt",ios::in);
    file2.seekg(0);
    file2.read((char*)&Emp_1,sizeof(Emp_1));
    printf("
Name :%s",Emp_1.Name);
    printf("
Employee ID :%d",Emp_1.Employee_ID);
    printf("
Salary :%d",Emp_1.Salary);
    file2.close();
    return 0;
}

실행 결과

Name: John
Employee ID: 2121
Salary: 11000

정리 및 주의 사항

이처럼 C++에서는 fstream 라이브러리의 write()와 read() 함수를 활용해 클래스 객체 전체를 파일에 직렬화하고, 다시 역직렬화하여 불러올 수 있습니다. 다만 몇 가지 유의할 점이 있습니다.

  • 객체는 이진(binary) 형태로 저장되므로, 파일을 일반 텍스트 편집기로 열면 사람이 읽기 어려운 형태로 보일 수 있습니다.
  • std::string처럼 내부적으로 동적 메모리를 사용하는 멤버 변수가 포함된 객체를 이진 방식으로 그대로 쓰거나 읽으면 프로그램 오류가 발생할 수 있으므로, 고정 크기 배열(char 배열 등)을 사용하거나 직렬화 로직을 별도로 구현하는 것이 안전합니다.
  • seekg(0) 함수는 파일의 읽기 위치를 처음으로 되돌리는 역할을 하며, 쓰기 후 같은 파일을 다시 읽을 때 필요합니다.