Programming Languages/C++

파일 입출력

newclass 2025. 3. 28. 10:04

9.2 파일 입출력

C++는 파일 작업을 위한 포괄적인 기능을 제공합니다.

9.2.1 텍스트 파일 읽기/쓰기

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

int main() {
    // 파일 쓰기
    std::ofstream outFile("example.txt");
    
    if (!outFile) {
        std::cerr << "파일을 열 수 없습니다." << std::endl;
        return 1;
    }
    
    outFile << "Hello, C++ File I/O!" << std::endl;
    outFile << "이것은 두 번째 줄입니다." << std::endl;
    outFile << "숫자도 쓸 수 있습니다: " << 12345 << std::endl;
    
    outFile.close();
    std::cout << "파일 쓰기 완료." << std::endl;
    
    // 파일 읽기
    std::ifstream inFile("example.txt");
    
    if (!inFile) {
        std::cerr << "파일을 열 수 없습니다." << std::endl;
        return 1;
    }
    
    std::string line;
    std::cout << "\n파일 내용:" << std::endl;
    
    // 한 줄씩 읽기
    while (std::getline(inFile, line)) {
        std::cout << line << std::endl;
    }
    
    inFile.close();
    
    // 다른 방식으로 파일 읽기
    inFile.open("example.txt");
    
    if (!inFile) {
        std::cerr << "파일을 열 수 없습니다." << std::endl;
        return 1;
    }
    
    std::cout << "\n단어별 읽기:" << std::endl;
    std::string word;
    
    // 단어별 읽기
    while (inFile >> word) {
        std::cout << word << " ";
    }
    std::cout << std::endl;
    
    inFile.close();
    
    return 0;
}

9.2.2 이진 파일 읽기/쓰기

#include <iostream>
#include <fstream>
#include <vector>

struct Person {
    char name[50];
    int age;
    double salary;
};

int main() {
    // 이진 파일 쓰기
    std::ofstream outFile("data.bin", std::ios::binary);
    
    if (!outFile) {
        std::cerr << "파일을 열 수 없습니다." << std::endl;
        return 1;
    }
    
    // 단일 값 쓰기
    int num = 12345;
    outFile.write(reinterpret_cast<char*>(&num), sizeof(num));
    
    // 구조체 쓰기
    Person person = {"홍길동", 30, 50000.0};
    outFile.write(reinterpret_cast<char*>(&person), sizeof(Person));
    
    // 배열 쓰기
    std::vector<int> numbers = {10, 20, 30, 40, 50};
    int size = numbers.size();
    
    outFile.write(reinterpret_cast<char*>(&size), sizeof(size));
    outFile.write(reinterpret_cast<char*>(numbers.data()), size * sizeof(int));
    
    outFile.close();
    std::cout << "이진 파일 쓰기 완료." << std::endl;
    
    // 이진 파일 읽기
    std::ifstream inFile("data.bin", std::ios::binary);
    
    if (!inFile) {
        std::cerr << "파일을 열 수 없습니다." << std::endl;
        return 1;
    }
    
    // 단일 값 읽기
    int readNum;
    inFile.read(reinterpret_cast<char*>(&readNum), sizeof(readNum));
    std::cout << "읽은 숫자: " << readNum << std::endl;
    
    // 구조체 읽기
    Person readPerson;
    inFile.read(reinterpret_cast<char*>(&readPerson), sizeof(Person));
    std::cout << "이름: " << readPerson.name << ", 나이: " << readPerson.age 
              << ", 급여: " << readPerson.salary << std::endl;
    
    // 배열 읽기
    int readSize;
    inFile.read(reinterpret_cast<char*>(&readSize), sizeof(readSize));
    
    std::vector<int> readNumbers(readSize);
    inFile.read(reinterpret_cast<char*>(readNumbers.data()), readSize * sizeof(int));
    
    std::cout << "읽은 배열: ";
    for (int n : readNumbers) {
        std::cout << n << " ";
    }
    std::cout << std::endl;
    
    inFile.close();
    
    return 0;
}

9.2.3 파일 스트림 상태 관리

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

int main() {
    std::ifstream file("nonexistent.txt");
    
    // 파일 열기 상태 확인
    if (!file) {
        std::cerr << "파일을 열 수 없습니다." << std::endl;
        std::cout << "failbit: " << file.fail() << std::endl;
        std::cout << "badbit: " << file.bad() << std::endl;
        std::cout << "eofbit: " << file.eof() << std::endl;
        
        // 스트림 상태 초기화
        file.clear();
    }
    
    // 새 파일 생성하고 상태 테스트
    std::ofstream outFile("test.txt");
    outFile << "테스트 문자열" << std::endl;
    outFile.close();
    
    file.open("test.txt");
    
    if (file) {
        std::string line;
        std::getline(file, line);
        std::cout << "파일 내용: " << line << std::endl;
        
        // 다시 읽기 시도 (EOF에 도달함)
        std::getline(file, line);
        
        // 스트림 상태 확인
        std::cout << "읽기 후 eofbit: " << file.eof() << std::endl;
        std::cout << "읽기 후 failbit: " << file.fail() << std::endl;
        
        // 스트림 상태 초기화 및 파일 포인터 이동
        file.clear();
        file.seekg(0, std::ios::beg);  // 파일 시작 위치로 이동
        
        // 다시 읽기
        std::getline(file, line);
        std::cout << "파일 포인터 이동 후 내용: " << line << std::endl;
    }
    
    file.close();
    
    return 0;
}

9.2.4 파일 포인터 조작

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

int main() {
    // 파일 생성
    std::ofstream outFile("positions.txt");
    outFile << "Line 1: This is the first line." << std::endl;
    outFile << "Line 2: This is the second line." << std::endl;
    outFile << "Line 3: This is the third line." << std::endl;
    outFile.close();
    
    // 파일 열기
    std::fstream file("positions.txt", std::ios::in | std::ios::out);
    
    if (!file) {
        std::cerr << "파일을 열 수 없습니다." << std::endl;
        return 1;
    }
    
    // 현재 위치 확인
    std::streampos currentPos = file.tellg();
    std::cout << "초기 위치: " << currentPos << std::endl;
    
    // 파일 끝으로 이동
    file.seekg(0, std::ios::end);
    std::cout << "파일 크기: " << file.tellg() << " 바이트" << std::endl;
    
    // 파일 시작으로 이동
    file.seekg(0, std::ios::beg);
    
    // 첫 번째 줄 읽기
    std::string line;
    std::getline(file, line);
    std::cout << "첫 번째 줄: " << line << std::endl;
    
    // 현재 위치 저장
    currentPos = file.tellg();
    std::cout << "첫 번째 줄 이후 위치: " << currentPos << std::endl;
    
    // 세 번째 줄로 이동하기 위해 나머지 두 번째 줄 읽기
    std::getline(file, line);
    
    // 현재 위치에서 쓰기
    file.seekp(file.tellg());
    file << "Line 3 Modified: This line was changed." << std::endl;
    
    // 파일 다시 읽기
    file.seekg(0, std::ios::beg);
    std::cout << "\n수정된 파일 내용:" << std::endl;
    
    while (std::getline(file, line)) {
        std::cout << line << std::endl;
    }
    
    file.close();
    
    return 0;
}