[C++] 파일 입출력

    파일의 종류

    파일의 종류에는 텍스트 파일과 바이너리 파일 두가지가 있다. 

    텍스트파일 : 내용이 텍스트, 문자만으로 작성된 파일. 메모장 파일 , 소스 코드, xml문서 등.

    바이너리 파일 : 파일 내용을 텍스트만으로 표현 불가. mp3, jpeg, hwp, obj, exe 등 컴파일된 코드나 실행 파일.

     

    C++ 표준 파입 입출력

    스트림 입출력 방식 지원

    일반적으로 파일입출력을 위해선 <fstream> 라이브러리 이용한다.

     

    파일 입출력 모드

    fsream은 텍스트 I/O와 바이너리 I/O 방식을 모두 지원

    텍스트 I/O : 문자 단위로 파일 읽기/쓰기

    바이너리 I/O  :  바이트 단위 파일 읽기/쓰기, 바이너리 I/O 방식으로 텍스트 파일의 입출력 사용 가능

     

    파일 입출력 스트림은 프로그램과 파일을 연결시켜준다.

    파일 입력: ">>" 연산자, get(), read() 함수 사용 => 연결된 장치로부터 읽어온다.

    파일 출력: "<<" 연산자, put(), write() 함수 사용 => 연결된 장치에 작성한다.

     

    << 연산자를 이용한 파일 출력.
    #include <fstream>
    #include <iostream>
    using namespace std;
    
    int main() {
    	ofstream fout;
    	fout.open("song.txt");
    
    	//ofstream fout("c:\\temp\\student.txt);
    
    	if (!fout) {
    		cout << "파일 열기에 실패하였습니다.";
    		return 0;
    	}
    
    	int age = 21;
    	char singer[] = "kim";
    	char song[] = "Yesterday";
    	fout << age << '\n';
    	fout << singer << endl;
    	fout << song << endl;
    
    	fout.close();
    }

     

    >> 연산자를 이용한 파일 입력
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main() {
    	ifstream fin;
    	fin.open("song.txt");
    	//fin,open("c:\\temp\\student.txt);
    
    	if (!fin) {
    		cout << "파일을 여는데 실패했습니다.";
    		return 0;
    	}
    
    	char name[10], day[20];
    	int age;
    
    	fin >> age;
    	fin >> name;
    	fin >> day;
    
    	cout << age << endl;
    	cout << name << endl;
    	cout << day << endl;
    
    	fin.close();
    }
    21
    kim
    Yesterday

    파일 입력은 파일 출력과 방법이 유사하다.

     

    파일 모드(file mode)

    파일 모드란, 파일 입출력의 구체적인 작업 형태를 지정하는 것이다. 파일을 열 때 수행할 작업을 미리 지정하고 여는 것,

     

    get() 함수를 이용해서 텍스트 파일 읽기
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main() {
    	const char* file = "c:\\windows\\System.ini";
    
    	ifstream fin(file);
    	if (!fin) {
    		cout << file << "열기 오류" << endl;
    		return 0;
    	}
    
    	int count = 0;
    	int c;
    	while ((c = fin.get()) != EOF) {
    		cout << (char)c;
    		count++;
    	}
    	cout << "읽은 바이트 수는 " << count << endl;
    	fin.close();
    }
    ; for 16-bit app support
    [386Enh]
    woafont=dosapp.fon
    EGA80WOA.FON=EGA80WOA.FON
    EGA40WOA.FON=EGA40WOA.FON
    CGA80WOA.FON=CGA80WOA.FON
    CGA40WOA.FON=CGA40WOA.FON
    
    [drivers]
    wave=mmdrv.dll
    timer=timer.drv
    
    [mci]
    읽은 바이트 수는 206

     

    텍스트 I/O로 파일을 읽을 때에는, enter키 '\r' '\n' 두개를 하나의 입력으로 본다. 캐리지 리턴과 라인피드에 대한 설명은 이전 포스팅에서 다룬적 있으니 넘어가겠다. 

     

    get() 메소드를 이용해 파일을 읽다 보면 결국 언젠가는 파일의 끝에 도달하게 된다. get() 메소드가 파일의 끝, EOF를 만나면 EOF(-1)을 반환한다. 따라서 파일을 읽을 때에는, 항상 내가 읽고 있는 것이 EOF가 아닌지 검사를 해야 한다. 

     

    +EOF를 만난다는 건 무슨 말일까? => 파일포인터가 EOF이전 문자를 읽고 마지막 문자에 뒤로 이동한다. 파일 포인터가 파일의 끝에 있는 상태에서 get() 메소드를 호출해 한 번 더 읽게되면 EOF값이 반환된다.

     

    int c;
    while ((c=fin.get()) != EOF) {
    	파일에서 읽어온 c 값을 처리한다.
    }

     

    getline()을 이용하여 라인단위로 읽기

    getline 함수를 이용하는 방법은 두 가지가 있다.

    하나는 istream의 getline 함수를 이용하는 방법이고,  또 다른 하나는 string의 getline() 함수를 이용하는 방법이다.

    istream의 getline() 함수 이용
    
    char buf[81];
    ifstream fin("c:\\windows\\system.ini");
    while(fin.getline(buf,81)){
    	//buf 값 처리
    }
    전역함수 getline() 함수 이용
    
    string line;
    ifstream fin("c:\\windows\\system.ini");
    while(getline(fin, line)) {
    	//line 처리
    }

    while문 안에 getline 함수를 사용하면, EOF를 만나기 전까지 파일을 라인단위로 읽는다.

    댓글