C++ Espresso 제13장 입출력과 파일처리
이번 장에서 학습할 내용 입출력과 파일처리에 대하여 살펴봅시다. 파일 입출력 텍스트 파일과 이진 파일 순차 파일과 랜덤 파일
스트림(stream) 스트림(stream)은 “순서가 있는 데이터의 연속적인 흐름”이다. 스트림은 입출력을 물의 흐름처럼 간주하는 것이다.
입출력 관련 클래스들 ostream istream ifstream ofstream iostream fstream stringstream fstream istringstream ostringstream
파일 처리의 순서 파일을 다룰 때는 반드시 다음과 같은 순서를 지켜야 한다.
<<과 >>을 이용한 입출력 입력 ifstream is; is.open("score.txt"); int number; is >> number; 출력 ofstream os; os.open("result.txt"); os << number;
예제 #1 학생 데이터를 파일에 저장하고 읽어보자. int number; // 학번 char name[30]; // 이름 int score; // 성적
예제 #include <iostream> #include <fstream> // 파일 입출력을 하려면 헤더 파일을 포함하여야 한다. using namespace std; int main() { ifstream is; is.open("score.txt"); if( !is ) { // ! 연산자 오버로딩 cerr << "파일 오픈에 실패하였습니다" << endl; exit( 1 ); } int number; //학번 char name[30]; // 이름 int score; // 성적 is >> number >> name >> score;
예제 score.txt result.txt ofstream os; os.open("result.txt"); os << number << " " << name << " " << score << endl; is.close(); os.close(); return 0; } score.txt 20100001 홍길동 100 20100002 김유신 90 20100003 강감찬 80 result.txt 20100001 홍길동 100
멤버 함수 이용 입출력 #include <iostream> #include <fstream> // 파일 입출력을 하려면 헤더 파일을 포함하여야 한다. using namespace std; int main() { ifstream is; is.open("score.txt"); if( !is ) { // ! 연산자 오버로딩 cerr << "파일 오픈에 실패하였습니다" << endl; exit( 1 ); } char c; is.get(c); // 하나의 문자를 읽는다. while(! is.eof() ) cout << c; is.get(c); is.close(); return 0;
멤버 함수 이용 입출력 파일 score.txt 20100001 홍길동 100 20100002 김유신 90 20100003 강감찬 80 실행 결과 20100001 홍길동 100 20100002 김유신 90 20100003 강감찬 80 계속하려면 아무 키나 누르십시오 . . .
키보드에서 받은 문자 저장 #include <iostream> #include <fstream> // 파일 입출력을 하려면 헤더 파일을 포함하여야 한다. using namespace std; int main() { ofstream os; char c; os.open("test.txt"); while( cin.get(c) ) os.put(c); } os.close(); return 0;
키보드에서 받은 문자 저장 파일 test.txt This is a test. 실행 결과 This is a test. ^Z Press any key to continue
각줄에 번호를 붙이는 예제 #include <iostream> #include <fstream> using namespace std; int main() { ifstream is; ofstream os; is.open("score.txt"); if( is.fail() ){ cerr << "파일 오픈 실패" << endl; exit(1); } os.open("result.txt"); if( os.fail() ){
각줄에 번호를 붙이는 예제 char c; int line_number=1; is.get(c); os << line_number << ": "; while(! is.eof() ) { os << c; if( c == '\n' ){ line_number++; } is.close(); os.close(); return 0;
각줄에 번호를 붙이는 예제 파일 score.txt 20100001 홍길동 100 20100002 김유신 90 20100003 강감찬 80 파일 result.txt 1: 20100001 홍길동 100 2: 20100002 김유신 90 3: 20100003 강감찬 80
출력 형식 지정 cout.precision(3); // 소수점 이하 지리수를 3자리로 설정 cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.setf(ios::left); cout.setf(ios::left | ios::showpoint); cout.unsetf(ios::uppercase); // 설정 해제
중간 점검 문제 1. 스트림의 장점은 무엇인가? 2. 사용자로부터 입력을 받아서 무조건 파일에 저장하는 프로그램을 작성하라.
텍스트와 이진 파일
텍스트 파일(text file) 텍스트 파일은 사람이 읽을 수 있는 텍스트가 들어 있는 파일 (예) C 프로그램 소스 파일이나 메모장 파일 텍스트 파일은 아스키 코드를 이용하여 저장 텍스트 파일은 연속적인 라인들로 구성
이진 파일(binary file) 이진 파일은 사람이 읽을 수는 없으나 컴퓨터는 읽을 수 있는 파일 이진 데이터가 직접 저장되어 있는 파일 이진 파일은 텍스트 파일과는 달리 라인들로 분리되지 않는다. 모든 데이터들은 문자열로 변환되지 않고 입출력 이진 파일은 특정 프로그램에 의해서만 판독이 가능 (예) C 프로그램 실행 파일, 사운드 파일, 이미지 파일
텍스트와 이진 파일의 저장 방법 비교
이진 파일 입출력 ofstream os; os.open("test.dat", ofstream::binary); int x=5; os.write((char*)&x, sizeof(int));
예제 #include <iostream> #include <fstream> using namespace std; int main() { int buffer[] = { 10, 20, 30, 40, 50 }; ofstream os; os.open("test.dat",ofstream::binary); if( os.fail() ) cout << "binary.txt 파일을 열 수 없습니다." << endl; exit(1); } os.write((char *)&buffer, sizeof(buffer)); os.close(); return 0;
실행 결과 파일 test.dat
예제 int main() { struct Score { int number; char name[30]; int score; } grades[] = { {20100001, "홍길동", 100}, {20100002, "김유신", 90}, {20100003, "강감찬", 80} }; ofstream os; os.open("test.dat",ofstream::binary); if( os.fail() ) cout << "test.dat 파일을 열 수 없습니다." << endl; exit(1); } os.write((char *)&grades, sizeof(grades)); os.close(); return 0;
실행 결과 파일 test.dat
중간 점검 문제 1. 정수 10은 텍스트 파일에서는 어떻게 저장되는가? 2. 정수 10은 이진 파일에서는 어떻게 저장되는가?
임의 접근 파일 순차 접근(sequential access) 방법: 데이터를 파일의 처음부터 순차적으로 읽거나 기록하는 방법 임의 접근(random access) 방법: 파일의 어느 위치에서든지 읽기와 쓰기가 가능한 방법
임의 접근 파일의 원리 파일 위치 표시자: 읽기와 쓰기 동작이 현재 어떤 위치에서 이루어지는 지를 나타낸다. 강제적으로 파일 위치 표시자를 이동시키면 임의 접근이 가능 파일 위치 표시자
임의 접근 관련 함수 seekg(long offset, seekdir way); is.seekg(ios::beg, 100); is.seekg(ios::end, 0); is.seekg(ios::cur, -100);
예제 const int SIZE=1000; void init_table(int table[], int size); int main() { int table[SIZE]; int data; long pos; // 배열을 초기화한다. init_table(table, SIZE); // 이진 파일을 쓰기 모드로 연다. ofstream os; os.open("test.dat",ofstream::binary); if( os.fail() ) cout << "test.dat 파일을 열 수 없습니다." << endl; exit(1); }
예제 // 배열을 이진 모드로 파일에 저장한다. os.write((char *)table, sizeof(table)); os.close(); // 이진 파일을 읽기 모드로 연다. ifstream is; is.open("test.dat",ofstream::binary); if( is.fail() ) { cout << "test.dat 파일을 열 수 없습니다." << endl; exit(1); }
예제 // 사용자가 선택한 위치의 정수를 파일로부터 읽는다. while(1) { cout <<"파일에서의 위치를 입력하십시요(0에서 999, 종료-1): "; cin >> pos; if( pos == -1 ) break; is.seekg(pos*sizeof(int), ios::beg); is.read((char *)&data, sizeof(int)); cout << pos << " 위치의 값은" << data << " 입니다." << endl; } is.close(); return 0; // 배열을 인덱스의 제곱으로 채운다. void init_table(int table[], int size) int i; for(i = 0; i < size; i++) table[i] = i * i;
예제 파일에서의 위치를 입력하십시요(0에서 999, 종료 -1): 3 3 위치의 값은 9입니다. 파일에서의 위치를 입력하십시요(0에서 999, 종료 -1): 9 9 위치의 값은 81입니다. 파일에서의 위치를 입력하십시요(0에서 999, 종료 -1): -1
중간 점검 문제 1. 파일의 처음으로 파일 위치 표시자를 이동시키는 문장을 작성하라. 2. 파일의 끝으로 파일 위치 표시자를 이동시키는 문장을 작성하라.
Q & A