Topic 1: 파일 스트림 기초 - 데이터를 파일에 저장하고 불러오기 📝
🎯 학습 목표
- 파일 입출력의 필요성과 개념을 이해할 수 있다
- ifstream, ofstream, fstream의 차이점을 구분할 수 있다
- 텍스트 파일을 읽고 쓰는 방법을 익힐 수 있다
- 파일 처리 과정에서 예외 처리를 할 수 있다
- 실제 프로젝트에서 파일을 활용한 데이터 저장을 구현할 수 있다
📖 일기장과 파일 입출력
프로그램이 종료되면 메모리에 있던 모든 데이터가 사라져요! 📱💨
일기장 비유로 이해해봅시다:
-
메모리 = 머릿속 기억 🧠
- 빠르지만 전원이 꺼지면 사라짐
- 임시 저장용
-
파일 = 일기장 노트 📔
- 느리지만 영구 보관 가능
- 언제든 다시 읽을 수 있음
// 메모리만 사용하는 경우
int gameScore = 1500; // 프로그램 종료 시 사라짐 😢
// 파일에 저장하는 경우
// score.txt 파일에 1500을 저장 → 영구 보관! 😊📂 파일 스트림 3형제
C++에서는 3가지 파일 스트림을 제공합니다:
1. ifstream - 읽기 전용 📖
ifstream inputFile; // input file stream
// 파일을 읽기만 할 때 사용2. ofstream - 쓰기 전용 ✍️
ofstream outputFile; // output file stream
// 파일에 쓰기만 할 때 사용3. fstream - 읽기/쓰기 겸용 🔄
fstream file; // file stream
// 읽기와 쓰기를 모두 할 때 사용📝 첫 번째 파일 쓰기 예제
게임 플레이어 정보 저장
#include <iostream>
#include <fstream> // 파일 스트림 헤더
#include <string>
using namespace std;
int main() {
// 파일에 쓰기 위한 스트림 생성
ofstream gameFile("player_data.txt");
// 파일이 정상적으로 열렸는지 확인
if (!gameFile.is_open()) {
cout << "❌ 파일을 열 수 없습니다!" << endl;
return 1;
}
// 플레이어 정보
string playerName = "용감한전사";
int level = 25;
int gold = 1500;
// 파일에 데이터 쓰기 (cout과 같은 방식!)
gameFile << "=== 게임 세이브 데이터 ===" << endl;
gameFile << "플레이어명: " << playerName << endl;
gameFile << "레벨: " << level << endl;
gameFile << "골드: " << gold << "💰" << endl;
gameFile << "저장 시각: 2024-03-15 14:30" << endl;
// 파일 닫기 (중요!)
gameFile.close();
cout << "✅ 게임 데이터가 저장되었습니다!" << endl;
return 0;
}생성된 player_data.txt 파일 내용:
=== 게임 세이브 데이터 ===
플레이어명: 용감한전사
레벨: 25
골드: 1500💰
저장 시각: 2024-03-15 14:30📖 파일 읽기 예제
저장된 게임 데이터 불러오기
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
// 파일에서 읽기 위한 스트림 생성
ifstream gameFile("player_data.txt");
// 파일이 정상적으로 열렸는지 확인
if (!gameFile.is_open()) {
cout << "❌ 저장 파일이 없습니다!" << endl;
return 1;
}
cout << "📂 게임 세이브 파일 로딩 중..." << endl;
cout << "================================" << endl;
string line;
// 파일의 모든 줄을 읽어서 출력
while (getline(gameFile, line)) {
cout << line << endl;
}
gameFile.close();
cout << "================================" << endl;
cout << "✅ 게임 데이터 로딩 완료!" << endl;
return 0;
}🎮 실전 예제: 게임 세이브/로드 시스템
완전한 게임 데이터 관리 시스템
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class GameSaveSystem {
private:
string filename = "game_save.txt";
public:
// 게임 데이터 저장
void saveGame(string playerName, int level, int hp, int mp, int gold) {
ofstream saveFile(filename);
if (!saveFile.is_open()) {
cout << "❌ 세이브 파일을 생성할 수 없습니다!" << endl;
return;
}
cout << "💾 게임 저장 중..." << endl;
// 구조화된 데이터 저장
saveFile << playerName << endl;
saveFile << level << endl;
saveFile << hp << endl;
saveFile << mp << endl;
saveFile << gold << endl;
saveFile.close();
cout << "✅ " << playerName << "의 게임이 저장되었습니다!" << endl;
}
// 게임 데이터 로드
void loadGame() {
ifstream loadFile(filename);
if (!loadFile.is_open()) {
cout << "❌ 저장된 게임 파일이 없습니다!" << endl;
return;
}
cout << "📂 게임 로딩 중..." << endl;
string playerName;
int level, hp, mp, gold;
// 순서대로 데이터 읽기
loadFile >> playerName;
loadFile >> level;
loadFile >> hp;
loadFile >> mp;
loadFile >> gold;
loadFile.close();
// 로드된 데이터 출력
cout << "🎮 ==========================" << endl;
cout << " 플레이어: " << playerName << "⚔️" << endl;
cout << " 레벨: " << level << " 📊" << endl;
cout << " HP: " << hp << " ❤️" << endl;
cout << " MP: " << mp << " 💙" << endl;
cout << " 골드: " << gold << " 💰" << endl;
cout << "🎮 ==========================" << endl;
cout << "✅ 게임 로딩 완료!" << endl;
}
// 세이브 파일 존재 확인
bool hasSaveFile() {
ifstream checkFile(filename);
bool exists = checkFile.is_open();
checkFile.close();
return exists;
}
};
int main() {
GameSaveSystem saveSystem;
int choice;
cout << "🎮 게임 세이브/로드 시스템 🎮" << endl;
cout << "=============================" << endl;
while (true) {
cout << "1. 새 게임 시작 & 저장 💾" << endl;
cout << "2. 게임 로드 📂" << endl;
cout << "3. 종료 🚪" << endl;
cout << "선택: ";
cin >> choice;
switch (choice) {
case 1: {
cout << "🆕 새 게임을 시작합니다!" << endl;
string name;
cout << "플레이어 이름: ";
cin >> name;
// 기본 스탯으로 게임 시작
int level = 1;
int hp = 100;
int mp = 50;
int gold = 100;
cout << "⚔️ " << name << "의 모험이 시작됩니다!" << endl;
cout << "🎯 레벨 업 시뮬레이션..." << endl;
// 간단한 레벨업 시뮬레이션
for (int i = 0; i < 3; i++) {
level++;
hp += 20;
mp += 10;
gold += 50;
cout << "🎉 레벨 업! 현재 레벨: " << level << endl;
}
// 게임 저장
saveSystem.saveGame(name, level, hp, mp, gold);
break;
}
case 2: {
if (saveSystem.hasSaveFile()) {
saveSystem.loadGame();
} else {
cout << "❌ 저장된 게임이 없습니다!" << endl;
}
break;
}
case 3:
cout << "👋 게임을 종료합니다!" << endl;
return 0;
default:
cout << "❌ 잘못된 선택입니다!" << endl;
}
cout << endl;
}
return 0;
}🚨 파일 처리 시 주의사항
1. 항상 파일이 열렸는지 확인하기
if (!file.is_open()) {
cout << "파일 열기 실패!" << endl;
return;
}2. 파일 사용 후 닫기
file.close(); // 메모리 누수 방지!3. 파일 경로 주의
// 절대 경로
ofstream file("C:/Games/save.txt");
// 상대 경로 (추천)
ofstream file("data/save.txt");📊 파일 스트림 vs 콘솔 스트림
| 구분 | 콘솔 스트림 | 파일 스트림 |
|---|---|---|
| 출력 | cout << | fileOut << |
| 입력 | cin >> | fileIn >> |
| 대상 | 화면/키보드 | 파일 |
| 속도 | 빠름 | 상대적으로 느림 |
| 영속성 | 임시 | 영구 |
💡 핵심 정리
- 파일 입출력: 데이터를 영구적으로 저장하고 불러오는 기술
- ifstream: 파일에서 읽기 전용 (
>>연산자 사용) - ofstream: 파일에 쓰기 전용 (
<<연산자 사용) - fstream: 읽기/쓰기 모두 가능
- 파일 열기 확인:
is_open()함수로 검증 필수 - 파일 닫기:
close()함수로 리소스 해제 필수
✅ 실습 체크리스트
🚀 다음 시간 예고
다음 시간에는 이진 파일과 직렬화에 대해 알아볼 거예요!
- 텍스트 파일 vs 이진 파일의 차이점
- 이진 파일 읽기/쓰기 방법
- 객체를 파일에 저장하는 직렬화 기법
- 게임 캐릭터 정보를 이진 파일로 저장하기
“파일 입출력으로 데이터를 영원히 보관하세요! 📁✨”
Last updated on