본문 바로가기

Programming/C++ 2

[C++] 17. 파일 입출력

반응형

파일 입출력

  • 프로그램과 파일을 연결시키는 방법
  • 프로그램이 파일의 내용을 읽는 방법
  • 프로그램이 파일을 생성하고 파일을 기록하는 방법

C++에서는 입출력 클래스 패키지에서 파일 입출력을 표준 입출력처럼 다룬다.

 

파일에 기록하려면 ofstream 객체를 생성한 후,

삽입 연산자<<나 write() 같은 ostream 메서드를 사용한다.

 

파일로부터 내용을 읽으려면 ifstream객체를 생성한 후,

추출 연산자>>나 get()과 같은 istream 메서드를 사용한다.

 

그러나 파일들은 표준 입출력보다 더 많은 관리가 필요하다.

예를 들어, 새롭게 열리는 파일을 입력 스트림과 연결시켜야 한다.

 

파일은 읽기 전용 모드 또는 쓰기 전용 모드, 읽기/쓰기전용모드로 열 수 있다.

 

파일에 기록한다는 것은, 새로운 파일을 생성하는 것일 수도 있고, 

기존 파일을 대체하는 것일 수도 있고, 기존 파일의 뒤에 덧붙이는 것일 수도 있다.

그게 아니면 파일 안의 여기저기로 이동하는 것일 수도 있다.

 

C++은 이러한 작업을 돕는 새로운 클래스를 fream헤더파일에 정의한다.

파일 입력을 위한 ifstream 클래스와 파일 출력을 위한 ostream 클래스를 제공한다.

파일 입출력을 함께 처리하는 fstream 클래스도 제공한다.

 

이러한 클래스들은 iostream 헤더 파일에 있는 클래스들로부터 파생된 것이다.

 


간단한 파일 입출력

  1. 출력 스트림을 관리하기 위해 ofstream 객체를 생성한다
  2. 이 객체를 하나의 특별한 파일에 연결시킨다.
  3. cout을 사용하는 것과 동일한 방법으로 그 객체를 사용한다.
    차이는 출력이 화면으로 나가지 않고 파일로 나가는 것이다

이 작업을 위해서는 프로그램이 fstream 헤더 파일을 포함시켜야 한다.

이 파일을 포함시키면 모두는 아니지만 대부분의 컴파일러에서 iostream 파일이 자동으로 포함된다.

따라서 iostream을 명시적으로 포함시킬 필요가 없다. 그 다음에 ofstream 객체를 선언한다.

 

ostream fout;	//fout이라는 ofstream 객체를 생성한다.

그 다음에 open()메서드를 이용해 이 객체를 하나의 특별한 파일과 연결시킨다.

 

jar.txt를 출력하는 예

fout.open("jar.txt")	//fout 객체 생성, jar.txt와 연결

생성자를 사용해, 객체 생성과 파일 연결을 하나의 구문으로 결합할 수 있다.

ofstream fout("jar.txt");	//fout 객체 생성, jar.txt와 연결

fout을 cout처럼 사용할 수 있다.

두 단어 Dull Data를 파일에 기록하는 예

fout<<"Dull Data";

ostream은 ofstream 클래스의 기초 클래스로, 다양한 삽입 연산자들의 정의, 출력 형식 지정 메서드들, 조정자들을 포함하여 모든 ofstream 클래스는 버퍼를 경유하는 출력을 사용한다.

 

fout과 같은 ofstream 객체를 선언하면, 프로그램은 출력 버퍼로 사용할 공간을 대입한다.

두 개의 ofstream 객체를 생성하면, 프로그램은 두 객체를 위해 각각 하나씩 두 개의 버퍼를 대입한다.

 

fout과 같은 ofstream 객체는 프로그램으로부터 한 바이트씩 흐러 나오는 출력을 모아 두었다가,

버퍼가 가득 차면 버퍼의 내용을 목적지 파일로 한 묶음으로 전송한다.

[디스크 드라이브는 큰 덩어리로 데이터를 전송하도록 설계되어 있기 때문에]

 

출력을 위해 어떤 파일을 열 때, 그 이름을 가진 파일이 없으면 그 이름으로 새로운 파일이 생성된다.

파일을 열기 전부터 그 이름을 가진 파일이 있으면, 그 파일을 열고 파일의 내용을 비워서, 출력이 없는 파일로 만든다.

[파일을 열고 내용을 유지하는 방법은 나중에 설명한다.]

 


파일을 읽는 것과 기록하는 것은 비슷하다.

  1. 입력 스트림 관리하는 ifstream 객체 생성
  2. 이 객체를 하나의 파일에 연결
  3. cin 처럼 그 객체를 사용

먼저 fstream 헤더 파일 포함시킨다.

ifstream 객체를 생성하고 원하는 파일 이름과 연결시킨다.

//두 개의 구문
instream. fin;				//fin이라는 ifstream 객체를 생성한다.
fin.open("jellyjar.dat")	//읽기 위해 jellyjar.dat를 연다.


//하나의 구문
ifstream fis("jamjar.dat")	//fis를 생성하고 jamjar.dat와 연결한다.

 

fin과 fis의 사용 예

char ch;
fin>>ch;		//jellyjar.dat 파일에서 한 문자를 읽는다.
char buf[80];
fin >> buf;		//파일에서 한 단어를 읽는다.
fin.getline(buf, 80); 	//파일에서 한 행을 읽는다.
string line;
getline(fin, line);	//파일로부터 문자열 객체에 읽는다.

출력과 마찬가지로, 입력도 버퍼를 사용한다.

fin과 같은 ifstream 객체를 생성하면, fin 객체가 관리하는 입력 버퍼가 생성된다.

 

입력 스트림 객체와 출력 스트림 객체의 수명이 다했을때 [프로그램이 종료될 때처럼]

파일과의 연결은 자동으로 닫힌다.

 

수동으로 파일과의 연결 닫는 방법

fout.close();	//파일과의 출력 연결을 닫는다.
fout.open();	//파일과의 입력 연결을 닫는다.

연결을 닫는 경우에도 스트림은 유지된다. [다시 연결도 가능하다.]

 

 

파일 이름을 요청하는 예제

[프로그램은 그 이름을 가지는 파일을 생성하고, 정보를 저장 후 닫는다.

파일을 닫으면 버퍼가 지워지고, 이것은 파일 갱신을 보장한다.

프로그램은 읽기 위해 파일을 다시 열고, 그 내용을 화면에 출력한다.

프로그램은 파일이름을 읽어 string객체에 넣고, c_str() 메서드를 사용해 입출력 클래스 생성자를 위한 c 스타일 매개변술르 제공한다.]

// fileio.cpp -- 파일에 저장한다
#include <iostream> // 이것은 많은 시스템에서 필요 없다
#include <fstream>
#include <string>

int main()
{
    using namespace std;
    string filename;

    cout << "새 파일을 위한 이름을 입력하십시오: ";
    cin >> filename;

// 새 파일을 위한 출력 스트림 객체를 fout이라는 이름으로 생성한다
    ofstream fout(filename.c_str());

    fout << "비밀 번호 노출에 주의하십시오.\n";        	// 파일에 기록한다
    cout << "비밀 번호를 입력하십시오: ";   		// 화면에 출력한다
    float secret;
    cin >> secret;
    fout << "귀하의 비밀 번호는 " << secret << "입니다.\n";
    fout.close();           // 파일을 닫는다

// 새 파일을 위한 입력 스트림 객체를 fin이라는 이름으로 생성한다
    ifstream fin(filename.c_str());
    cout << filename << " 파일의 내용은 다음과 같습니다:\n";
    char ch;
    while (fin.get(ch))     // 파일로부터 한 문자를 읽는다
        cout << ch;         // 그 문자를 화면에 출력한다
    cout << "프로그램을 종료합니다.\n";
    fin.close();
    return 0; 
}

 

반응형