cpp

C++ 파일 입출력 심화

임베디드 친구 2024. 12. 21. 13:20
반응형

C++에서 파일 입출력은 다양한 데이터 처리를 가능하게 하는 중요한 기능입니다. 기본적인 파일 입출력뿐만 아니라 고급 기술을 활용하면 효율적인 데이터 관리를 구현할 수 있습니다. 오늘은 C++ 파일 입출력의 심화된 주제들을 다루고, 실용적인 예제를 통해 이를 구현하는 방법을 살펴보겠습니다.


1. 바이너리 파일 읽기 및 쓰기

바이너리 파일은 텍스트 파일과 다르게 데이터를 이진 형식으로 저장하여 크기를 줄이고, 빠르게 처리할 수 있는 장점이 있습니다.

바이너리 파일 쓰기

#include <iostream>
#include <fstream>

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

int main() {
    Person person = {"John Doe", 30, 175.5};

    std::ofstream outFile("person.dat", std::ios::binary);
    if (!outFile) {
        std::cerr << "파일을 열 수 없습니다!" << std::endl;
        return 1;
    }

    outFile.write(reinterpret_cast<char*>(&person), sizeof(person));
    outFile.close();

    std::cout << "바이너리 파일에 데이터를 저장했습니다." << std::endl;
    return 0;
}

바이너리 파일 읽기

#include <iostream>
#include <fstream>

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

int main() {
    Person person;

    std::ifstream inFile("person.dat", std::ios::binary);
    if (!inFile) {
        std::cerr << "파일을 열 수 없습니다!" << std::endl;
        return 1;
    }

    inFile.read(reinterpret_cast<char*>(&person), sizeof(person));
    inFile.close();

    std::cout << "이름: " << person.name << "\n"
              << "나이: " << person.age << "\n"
              << "키: " << person.height << std::endl;

    return 0;
}

2. 파일 포인터 위치 제어

파일 입출력에서는 파일 포인터를 원하는 위치로 이동하여 데이터를 읽거나 쓸 수 있습니다. 이를 통해 특정 부분만 효율적으로 처리할 수 있습니다.

파일 포인터 제어 예제

#include <iostream>
#include <fstream>

int main() {
    std::ofstream outFile("numbers.txt");
    for (int i = 1; i <= 10; ++i) {
        outFile << i << " ";
    }
    outFile.close();

    std::ifstream inFile("numbers.txt");
    if (!inFile) {
        std::cerr << "파일을 열 수 없습니다!" << std::endl;
        return 1;
    }

    inFile.seekg(4, std::ios::beg); // 파일 시작에서 4바이트 이동
    int number;
    inFile >> number;

    std::cout << "파일 포인터가 가리키는 숫자: " << number << std::endl;
    inFile.close();

    return 0;
}

3. 파일 스트림 상태 확인

파일 스트림의 상태를 확인하여 입출력 작업이 정상적으로 수행되었는지 확인할 수 있습니다.

스트림 상태 확인

#include <iostream>
#include <fstream>

int main() {
    std::ifstream inFile("nonexistent.txt");

    if (!inFile) {
        std::cerr << "파일을 열 수 없습니다!" << std::endl;
        return 1;
    }

    char ch;
    while (inFile.get(ch)) {
        std::cout << ch;
    }

    if (inFile.eof()) {
        std::cout << "\n파일 끝에 도달했습니다." << std::endl;
    } else if (inFile.fail()) {
        std::cerr << "파일 읽기 실패!" << std::endl;
    } else if (inFile.bad()) {
        std::cerr << "심각한 오류 발생!" << std::endl;
    }

    inFile.close();
    return 0;
}

4. 텍스트 파일 처리 심화: 특정 데이터 추출

텍스트 파일에서 특정 데이터를 추출하는 방법은 파일 입출력의 중요한 활용 사례입니다.

특정 데이터 추출 예제

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

int main() {
    std::ifstream inFile("data.txt");
    if (!inFile) {
        std::cerr << "파일을 열 수 없습니다!" << std::endl;
        return 1;
    }

    std::string line;
    while (std::getline(inFile, line)) {
        if (line.find("error") != std::string::npos) {
            std::cout << "에러 로그 발견: " << line << std::endl;
        }
    }

    inFile.close();
    return 0;
}

5. 파일과 예외 처리

파일 입출력에서 예외 처리를 활용하면 오류를 효과적으로 관리할 수 있습니다.

예외 처리 예제

#include <iostream>
#include <fstream>
#include <stdexcept>

int main() {
    try {
        std::ifstream inFile("data.txt");
        if (!inFile) {
            throw std::ios_base::failure("파일을 열 수 없습니다!");
        }

        char ch;
        while (inFile.get(ch)) {
            std::cout << ch;
        }

        inFile.close();
    } catch (const std::ios_base::failure& e) {
        std::cerr << "예외 발생: " << e.what() << std::endl;
    }

    return 0;
}

결론

오늘은 C++의 파일 입출력 심화 기능에 대해 살펴보았습니다. 바이너리 파일 처리, 파일 포인터 제어, 스트림 상태 확인, 텍스트 데이터 추출, 그리고 예외 처리 방법까지 다양한 주제를 다뤘습니다. 위의 예제 코드를 직접 실행하며 이해를 심화시켜 보세요.

C++ 파일 입출력은 데이터 관리의 기본이자 응용의 출발점입니다. 이를 효과적으로 활용하면 더욱 강력한 프로그램을 작성할 수 있습니다.

반응형

'cpp' 카테고리의 다른 글

C++ 멀티스레드 프로그래밍  (0) 2024.12.21
C++ 예외 처리 (Exception Handling)  (0) 2024.12.20
C++ STL(Standard Template Library)  (0) 2024.12.20
C++ 템플릿 - 제네릭 프로그래밍  (0) 2024.12.20
C++ 네임스페이스(namespace)  (0) 2024.12.20