Download presentation
Presentation is loading. Please wait.
1
명품 C++ 11장 C++ 입출력
2
스트림 스트림(stream) C++ 스트림 종류 데이터의 흐름, 혹은 데이타를 전송하는 소프트웨어 모듈
흐르는 시내와 유사한 개념 스트림의 양 끝에는 프로그램과 장치 연결 보낸 순서대로 데이터 전달 입출력 기본 단위 : 바이트 C++ 스트림 종류 입력 스트림 입력 장치, 네트워크, 파일로부터 데이터를 프로그램으로 전달하는 스트림 출력 스트림 프로그램에서 출력되는 데이터를 출력 장치, 네트워크, 파일로 전달 하는 스트림
3
C++ 입출력 스트림
4
C++ 입출력 스트림 버퍼 C++ 입출력 스트림은 버퍼를 가짐 키 입력 스트림의 버퍼 스크린 출력 스트림 버퍼 목적
입력장치로부터 입력된 데이터를 프로그램으로 전달하기 전에 일시 저장 키 입력 도중 수정 가능 <Backspace> 키가 입력되면 이전에 입력된 키를 버퍼에서 지움 프로그램은 사용자의 키 입력이 끝난 시점에서 읽음 <Enter> 키 : 키 입력의 끝을 의미 <Enter> 키가 입력된 시점부터 키 입력 버퍼에서 프로그램이 읽기 시작 스크린 출력 스트림 버퍼 프로그램에서 출력된 데이터를 출력 장치로 보내기 전에 일시 저장 출력 장치를 반복적으로 사용하는 비효율성 개선 버퍼가 꽉 차거나 강제 출력 명령 시에 출력 장치에 출력
5
키 입력 스트림과 버퍼의 역할
6
스크린 출력 스트림과 버퍼의 역할
7
C++ 표준은 스트림 입출력만 지원 입출력 방식 2가지 C++ 표준은 스트림 방식만 지원
스트림 입출력 방식(stream I/O) 스트림 버퍼를 이용한 입출력 방식 입력된 키는 버퍼에 저장 <Enter>키가 입력되면 프로그램이 버퍼에서 읽어가는 방식 출력되는 데이터는 일차적으로 스트림 버퍼에 저장 버퍼가 꽉 차거나, ‘\n’을 만나거나, 강제 출력 명령의 경우에만 버퍼가 출력 장치에 출 력 저 수준 입출력 방식(raw level console I/O) 키가 입력되는 즉시 프로그램에게 키 값 전달 <Backspace>키 그 자체도 프로그램에게 바로 전달 게임 등 키 입력이 즉각적으로 필요한 곳에 사용 프로그램이 출력하는 즉시 출력 장치에 출력 컴파일러마다 다른 라이브러리나 API 지원 C++ 프로그램의 호환성 낮음 C++ 표준은 스트림 방식만 지원 스트림 입출력은 모든 표준 C++ 컴파일러에 의해 컴파일됨 높은 호환성
8
구 표준 C++ 입출력 라이브러리의 약점 대표적인 구 표준 입출력 라이브러리 클래스 문자를 한 바이트의 char로 처리
ios, istream, ostream, iostream, ifstream, ofstream, fstream 문자를 한 바이트의 char로 처리 cin >>로 문자를 읽을 때, 한글 문자 읽을 수 없음 영어나 기호 : 1 바이트 한글 문자 : 2 바이트 char ch; cin >> ch; // 키보드로 문자 입력. 한글 문자 읽을 수 없음
9
새 표준 C++ 입출력 라이브러리 다양한 크기의 다국어 문자를 수용하기 위해, 입출력 라이브 러리를 템플릿으로 작성
스트림 입출력 기반 템플릿 클래스 basic_ios ios 입출력 스트림 템플릿 클래스 basic_istream basic_ostream istream ostream basic_iostream iostream 파일 입출력 템플릿 클래스 basic_ifstream basic_ofstream ifstream ofstream basic_fstream fstream 새 표준 입출력 라이브러리 – 템플릿으로 작성 템플릿에 char 타입으로 구체화한 클래스 - 구 표준의 이름 그대로 사용할 수 있음
10
typedef로 선언된 ios, istream, ostream, iostream 클래스
char 타입으로 구체화 typedef으로 선언된 iostream 2 바이트의 문자를 표현하는 wchar_t 타입으로 구체화
11
입출력 클래스 소개
12
표준 입출력 스트림 객체 C++ 프로그램이 실행될 때 자동으로 생겨나는 스트림 cin cout cerr clog
istream타입의 스트림 객체로서 키보드 장치와 연결 cout ostream타입의 스트림 객체로서 스크린 장치와 연결 cerr 오류 메시지를 출력할 목적 스트림 내부 버퍼 거치지 않고 출력 clog 스트림 내부에 버퍼 거쳐 출력
13
<iostream>에 선언된 스트림 객체들
14
ostream 멤버 함수 멤버 함수 의미 ostream& flush() 스트림 버퍼에 있는 내용을 강제 출력
ostream& put(char ch) ch의 한 문자를 스트림에 삽입하고 나중에 장치로 출력 ostream& write(char* str, int n) str에 있는 n 개의 문자를 스트림에 삽입하고 나중에 장치로 출력
15
예제 11–1 ostream 멤버 함수를 이용한 문자 출력
#include <iostream> using namespace std; int main() { // "Hi!"를 출력하고 다음 줄로 넘어간다. cout.put('H'); cout.put('i'); cout.put(33); cout.put('\n'); // "C++ "을 출력한다. cout.put('C').put('+').put('+').put(' '); char str[]="I love programming"; cout.write(str, 6); // str 배열의 6 개의 문자 "I love"를 스트림에 출력 } ASCII 코드 33은 ‘!’ 문자임 put() 메소드를 연결하여 사용할 수 있다. Hi! C++ I love
16
istream 멤버 함수 – 문자 입력, get() 함수
의미 int get() 입력 스트림에서 문자 읽어 리턴 istream& get(char& ch) 입력 스트림에서 문자 읽어 ch에 저장하고 리턴 int get()을 이용하여 한 라인의 문자들을 읽는 코드 int ch; while((ch = cin.get()) != EOF) { // EOF 는 -1 cout.put(ch); // 읽은 문자 출력 if(ch == '\n') break; // <Enter> 키가 입력되면 읽기 중단 } 입력 스트림의 끝인지 비교 istream& get(char& ch)을 이용하여 한 라인의 문자들을 읽는 코드 char ch; while(true) { cin.get(ch); // 입력된 키를 ch에 저장하여 리턴 if(cin.eof()) break; // EOF를 만나면 읽기 종료 cout.put(ch); // ch의 문자 출력 if(ch == '\n') break; // <Enter> 키가 입력되면 읽기 중단 } 입력 스트림의 끝인지 비교
17
ch = cin.get()의 실행 사례
18
예제 11-2 get()과 get(char&)을 이용한 한 줄의 문자 읽기
#include <iostream> using namespace std; void get1() { cout << "cin.get()로 <Enter> 키까지 입력 받고 출력합니다>>"; int ch; // EOF와의 비교를 위해 int 타입으로 선언 while((ch = cin.get()) != EOF) { // 문자 읽기. EOF 는 -1 cout.put(ch); // 읽은 문자 출력 if(ch == '\n') break; // <Enter> 키가 입력되면 읽기 중단 } void get2() { cout << "cin.get(char&)로 <Enter> 키까지 입력 받고 출력합니다>>"; char ch; while(true) { cin.get(ch); // 문자 읽기 if(cin.eof()) break; // EOF를 만나면 읽기 종료 cout.put(ch); // ch의 문자 출력 int main() { get1(); // cin.get()을 이용하는 사례 get2(); // cin.get(char&)을 이용하는 사례 예제 11-2 get()과 get(char&)을 이용한 한 줄의 문자 읽기 cin.get()로 <Enter> 키까지 입력 받고 출력합니다>>Do you love C++? Do you love C++? cin.get(char&)로 <Enter> 키까지 입력 받고 출력합니다>>Yes, I do. Yes, I do.
19
문자열 입력 입력 도중 <Enter>키(‘\n’)을 만날때 읽기를 중단하고 리턴
멤버 함수 의미 istream& get(char* s, int n) 입력 스트림에서 n-1개의 문자를 읽어 배열 s에 저장하고 마지막에 ‘\0’ 문자 삽입. 입력 도중 ‘\n’을 만나면 ‘\n’대신 ‘\0’를 삽입하고 리턴 char str[10]; cin.get(str, 10); // 최대 9개의 문자를 읽고 끝에 '\0'를 붙여 str 배열에 저장 cout << str; // str을 화면에 출력 입력 도중 <Enter>키(‘\n’)을 만날때 읽기를 중단하고 리턴 <Enter> 키(‘\n’)를 스트림 버퍼에 남김 다시 get()으로 문자열 읽기를 시도하면 입력 스트림에 남은 ‘\n’키를 읽게 되어 무한 루프에 빠짐 cin.get()이나 cin.ignore(1);를 통해 문자 1개(‘\n’)를 스트림에서 읽어 버려야 함.
20
예제 11–3 get(char*, int)을 이용한 문자열 입력
#include <iostream> #include <cstring> using namespace std; int main() { char cmd[80]; cout << "cin.get(char*, int)로 문자열을 읽습니다." << endl; while(true) { cout << "종료하려면 exit을 입력하세요 >> "; cin.get(cmd, 80); // 79개까지의 영어 문자 읽음. if(strcmp(cmd, "exit") == 0) { cout << "프로그램을 종료합니다...."; return 0; } else cin.ignore(1); // 버퍼에 남아 있는 <Enter> 키 ('\n') 제거 '\n'은 입력 스트림 버퍼에 남겨둠 38개 까지의 한글 무자 읽을 수 있음 이 부분을 제거하면 무한 루프에 빠짐 입력 버퍼에 남아 있는 ‘\n’ 제거 cin.get(char*, int)로 문자열을 읽습니다. 종료하려면 exit을 입력하세요 >> exi 종료하려면 exit을 입력하세요 >> exiT 종료하려면 exit을 입력하세요 >> exito 종료하려면 exit을 입력하세요 >> exit 프로그램을 종료합니다....
21
한 줄 읽기 char line[80]; cin.getline(line, 80); 메소드 의미
istream& get(char* s, int n, char delim=‘\n’) 입력 스트림에서 n-1개의 문자 읽기. 마지막에 ‘\0’를 삽입하여 문자열 완성. delim에 지정된 문자는 스트림에 남겨둠 istream& getline(char* s, int n, char delim=‘\n’) get()과 동일하나. delim 문자를 스트림에서 제거 char line[80]; cin.getline(line, 80);
22
예제 11-4 getline()으로 한 줄 단위로 문장 읽기
#include <iostream> using namespace std; int main() { char line[80]; cout << "cin.getline() 함수로 라인을 읽습니다." << endl; cout << "exit를 입력하면 루프가 끝납니다." << endl; int no = 1; // 라인 번호 while(true) { cout << "라인 " << no << " >> "; cin.getline(line, 80); // 79개까지의 문자 읽음 if(strcmp(line, "exit") == 0) break; cout << "echo --> ";; cout << line << endl; // 읽은 라인을 화면에 출력 no++; // 라인 번호 증가 } cin.getline() 함수로 라인을 읽습니다. exit를 입력하면 루프가 끝납니다. 라인 1 >> It's now or never. echo --> It's now or never. 라인 2 >> Come hold me tight. echo --> Come hold me tight. 라인 3 >> Kiss me my darling, be mine tonight. echo --> Kiss me my darling, be mine tonight. 라인 4 >> 엘비스 프레슬리 노래입니다. echo --> 엘비스 프레슬리 노래입니다. 라인 5 >> exit '\n'은 line에 삽입하지 않고, 스트림 버퍼에서 제거
23
입력 문자 건너 띄기와 문자 개수 알아내기 입력 스트림에서 문자 건너뛰기 최근에 읽은 문자 개수 리턴
멤버 함수 의미 istream& ignore(int n=1, int delim=EOF) 입력 스트림에서 n개의 문자를 제거. 중간에 delim 문자를 만나면 제거 종료 int gcount() 최근에 실행한 입력 스트림에서 읽기에 의해 읽은 문자 개수 리턴 cin.ignore(10); // 입력 스트림에 입력된 문자 중 10개 제거 cin.ignore(10, ‘;’); // 입력 스트림에서 10개의 문자 제거. 제거 도중 ‘;’을 만나면 종료 char line[80]; cin.getline(line, 80); int n = cin.gcount(); // 최근의 실행한 getline() 함수에서 읽은 문자의 개수 리턴
24
포맷 입출력 C++에서도 입출력 시 포맷 지정 가능 포맷 입출력 방법 3 가지 C 언어의 printf()와 유사 포맷 플래그
포맷 함수 조작자
25
포맷 플래그 포맷 플래그 입출력 스트림에서 입출력 형식을 지정하기 위한 플래그
포맷 플래그 값을 가진 ios 클래스의 멤버 변수 . dec showbase uppercase unitbuf skipws
26
ios 클래스에 정의된 포맷 플래그
27
포맷 플래그를 세팅하는 멤버 함수 cout.unsetf(ios::dec); // 10진수 해제
의미 long setf(long flags) flags를 스트림의 포맷 플래그로 설정. 이전 플래그 값 리턴 long unsetf(long flags) flags에 설정된 비트 값에 따라 스트림의 포맷 플래그 해제. 이전 플래그 값 리턴 cout.unsetf(ios::dec); // 10진수 해제 cout.setf(ios::hex); // 16진수로 설정 cout << 30 << endl; // 1e가 출력됨 cout.setf(ios::dec | ios::showpoint); // 10진수 표현과 동시에 실수에 // 소숫점이하 나머지는 0으로 출력 cout << 23.5 << endl; // 으로 출력
28
예제 11–5 setf(), unsetf()를 사용한 포맷 출력
#include <iostream> using namespace std; int main() { cout << 30 << endl; // 10진수로 출력 cout.unsetf(ios::dec); // 10진수 해제 cout.setf(ios::hex); // 16진수로 설정 cout << 30 << endl; cout.setf(ios::showbase); // 16진수로 설정 cout.setf(ios::uppercase); // 16진수의 A~F는 대문자로 출력 cout.setf(ios::dec | ios::showpoint); // 10진수 표현과 동시에 // 소숫점 이하 나머지는 0으로 출력 cout << 23.5 << endl; cout.setf(ios::scientific); // 실수를 과학산술용 표현으로 출력 cout.setf(ios::showpos); // 양수인 경우 + 부호도 함께 출력 cout << 23.5; } 30 출력 1e 출력 0x1e 출력 0X1E 출력 출력 30 1e 0x1e 0X1E E+001 E+001 E+001 출력 E+001 출력
29
포맷 함수 활용 멤버 함수 의미 int width(int minWidth)
char fill(char cFill) 필드의 빈 칸을 cFill 문자로 채우도록 지정. 이전 문자 값 리턴 int precision(int np) 출력되는 수의 유효 숫자 자릿수를 np 개로 설정. 정수 부분과 소수점 이하의 수의 자리를 모두 포함하고 소수점(.)은 제외 너비설정 cout.width(10); // 다음에 출력되는 "hello"를 10 칸으로 지정 cout << "Hello" << endl; cout.width(5); // 다음에 출력되는 정수 12를 5 칸으로 지정 cout << 12 << endl; Hello 12 cout << '%'; cout.width(10); // 다음에 출력되는 "Korea/"만 10 칸으로 지정 cout << "Korea/" << "Seoul/" << "City" <<endl; % Korea/Seoul/City 빈칸채우기 cout.fill('^'); cout.width(10); cout << "Hello" << endl; ^^^^^Hello 유효숫자자리수 cout.precision(5); cout << 11./3.; 3.6667
30
예제 11–6 width(), fill(), precision()을 사용한 포맷 출력
#include <iostream> using namespace std; void showWidth() { cout.width(10); // 다음에 출력되는 "hello"를 10 칸으로 지정 cout << "Hello" << endl; cout.width(5); // 다음에 출력되는 정수 12를 5 칸으로 지정 cout << 12 << endl; cout << '%'; cout.width(10); // 다음에 출력되는 "Korea/"만 10 칸으로 지정 cout << "Korea/" << "Seoul/" << "City" <<endl; } int main() { showWidth(); cout << endl; cout.fill('^'); cout.precision(5); cout << 11./3. << endl; Hello 12 % Korea/Seoul/City ^^^^^Hello ^^^12 %^^^^Korea/Seoul/City 3.6667
31
조작자 조작자 매개 변수 없는 조작자 매개 변수 있는 조작자
manipulator, 스트림 조작자(stream manipulator) 조작자는 함수 C++ 표준 라이브러리에 구현된 조작자 : 입출력 포맷 지정 목적 개발자 만의 조작자 작성 가능 : 다양한 목적 매개 변수 없는 조작자와 매개 변수를 가진 조작자로 구분 조작자는 항상 << 나 >> 연산자와 함께 사용됨 매개 변수 없는 조작자 매개 변수 있는 조작자 #include <iomanip> 필요 cout << hex << showbase << 30 << endl; cout << dec << showpos << 100 << endl; 0x1e +100 cout << setw(10) << setfill(‘^’) << “Hello” << endl; ^^^^^Hello
32
매개 변수 없는 조작자
33
매개 변수를 가진 조작자
34
boolalpha 조작자에 의해, “true”, “false” 문자열로 출력됨
예제 11–7 매개 변수 없는 조작자 사용 #include <iostream> using namespace std; int main() { cout << hex << showbase << 30 << endl; cout << dec << showpos << 100 << endl; cout << true << ' ' << false << endl; cout << boolalpha << true << ' ' << false << endl; } 0x1e +100 +1 +0 true false boolalpha 조작자에 의해, “true”, “false” 문자열로 출력됨
35
예제 11–8 매개 변수를 가진 조작자 사용 예 #include <iostream>
#include <iomanip> using namespace std; int main() { cout << showbase; // 타이틀을 출력한다. cout << setw(8) << "Number"; cout << setw(10) << "Octal"; cout << setw(10) << "Hexa" << endl; // 하나의 수를 십진수, 8진수, 16진수 형태로 한 줄에 출력한다. for(int i=0; i<50; i+=5) { cout << setw(8) << setfill('.') << dec << i; // 10진수 cout << setw(10) << setfill(' ') << oct << i; // 8진수 cout << setw(10) << setfill(' ') << hex << i << endl; // 16진수 } setw(8) 8 10 10 Number Octal Hexa x5 xa xf x14 x19 x1e x23 x28 x2d setfill(‘.’) showbase
36
삽입 연산자(<<) 삽입 연산자(<<) insertion operator, 삽입자라고도 부름
<< 연산자는 C++의 기본 연산자 : 정수 시프트 연산자 ostream 클래스에 중복 작성되어 있음 class ostream : virtual public ios { public : ostream& operator<< (int n); // 정수를 출력하는 << 연산자 ostream& operator<< (char c); // 문자를 출력하는 << 연산자 ostream& operator<< (const char* s); // 문자열을 출력하는 << 연산자 };
37
삽입 연산자의 실행 과정
38
사용자 삽입 연산자 만들기 개발자가 작성한 클래스의 객체를 << 연산자로 출력
다음 Point 클래스에 대해 cout << p;가 가능하도록 << 연산자를 작성하라. class Point { int x, y; public: Point(int x=0, int y=0) { this->x = x; this->y = y; } }; Point p(3,4); cout << p; (3,4)
39
cout << p;를 위한 << 연산자 만들기
40
예제 11-9 Point 객체를 스트림에 출력하는 << 연산자 작성
#include <iostream> using namespace std; class Point { // 한 점을 표현하는 클래스 int x, y; // private 멤버 public: Point(int x=0, int y=0) { this->x = x; this->y = y; } friend ostream& operator << (ostream& stream, Point a); }; // << 연산자 함수 ostream& operator << (ostream& stream, Point a) { stream << "(" << a.x << "," << a.y << ")"; return stream; int main() { Point p(3,4); // Point 객체 생성 cout << p << endl; // Point 객체 화면 출력 Point q(1,100), r(2,200); // Point 객체 생성 cout << q << r < endl; // Point 객체들 연속하여 화면 출력 private 필드 x, y를 접근하기 위해 이 함수를 Point 클래스에 friend로 선언함. (3,4) (1,100)(2,200)
41
예제 11–10 Book 클래스를 만들고 Book 객체를 스트림에 출력하는 << 연산자 작성
#include <iostream> #include <string> using namespace std; class Book { // 책을 표현하는 클래스 string title; string press; string author; public: Book(string title="", string press="", string author="") { this->title = title; this->press = press; this->author = author; } friend ostream& operator << (ostream& stream, Book b); // friend 선언 }; // << 연산자 함수 ostream& operator << (ostream& stream, Book b) { stream << b.title << "," << b.press << "," << b.author; return stream; int main() { Book book("소유냐 존재냐", "한국출판사", "에리히프롬"); // Book 객체 생성 cout << book; // Book 객체 book 화면 출력 소유냐 존재냐,한국출판사,에리히프롬
42
추출 연산자(>>) 추출 연산자(>>) extraction operator
ostream 클래스에 중복 작성되어 있음 class istream : virtual public ios { public : istream& operator>> (int& n); // 정수를 입력하는 >> 연산자 istream& operator>> (char& c); // 문자를 입력하는 >> 연산자 istream& operator>> (const char* s); // 문자열을 입력하는 >> 연산자 };
43
추출 연산자의 실행 과정 삽입 연산자의 실행 과정과 유사하므로 생략
44
사용자 추출 연산자 만들기 개발자가 작성한 클래스의 객체에 >> 연산자로 입력
다음 Point 클래스에 대해 cin >> p;가 가능하도록 >> 연산자를 작성하라. class Point { int x, y; public: Point(int x=0, int y=0) { this->x = x; this->y = y; } }; Point p; cin >> p; cout << p; x 좌표>>100 y 좌표>>200 (100,200) cin >> p 실행 cout << p 실행
45
cin >> p;를 위한 >> 연산자 만들기
이런 연산자 함수는 istream에 존재하지 않음 컴파일러에 의한 시도 class istream : virtual public ios { .... istream& operator >> (Point& p); ... }; cin . >> ( p ); 아래의 외부 연산자함수를 필요로 함 >> ( cin , p ); 컴파일러에 의한 시도 istream& operator >> (istream& stream, Point& a) { ... // stream으로부터 입력 받는 코드 return stream; }
46
예제 11-11 Point 객체를 입력 받는 >> 연산자 작성
#include <iostream> using namespace std; class Point { // 한 점을 표현하는 클래스 int x, y; // private 멤버 public: Point(int x=0, int y=0) { this->x = x; this->y = y; } friend istream& operator >> (istream& ins, Point &a); // friend 선언 friend ostream& operator << (ostream& stream, Point a); // friend 선언 }; istream& operator >> (istream& ins, Point &a) { // >> 연산자 함수 cout << "x 좌표>>"; ins >> a.x; cout << "y 좌표>>"; ins >> a.y; return ins; ostream& operator << (ostream& stream, Point a) { // << 연산자 함수 stream << "(" << a.x << "," << a.y << ")"; return stream; } int main() { Point p; // Point 객체 생성 cin >> p; // >> 연산자 호출하여 x 좌표와 y 좌표를 키보드로 읽어 객체 p 완성 cout << p; // << 연산자 호출하여 객체 p 출력 x 좌표>>100 y 좌표>>200 (100,200) cin >> p 실행 cout << p 실행
47
조작자 실행 과정
48
사용자 정의 조작자 함수 원형 매개 변수 없는 조작자의 경우
49
예제 11–12 사용자 정의 조작자 만들기 #include <iostream> using namespace std;
ostream& fivestar(ostream& outs) { return outs << "*****"; } ostream& rightarrow(ostream& outs) { return outs << "---->"; ostream& beep(ostream& outs) { return outs << '\a'; // 시스템 beep(삑 소리) 발생 int main() { cout << "벨이 울립니다" << beep << endl; cout << "C" << rightarrow << "C++" << rightarrow << "Java" << endl; cout << "Visual" << fivestar << "C++" << endl; 벨이 울립니다 C---->C++---->Java Visual*****C++
50
예제 11–13 사용자 정의 조작자 만들기 #include <iostream>
#include <string> using namespace std; istream& question(istream& ins) { cout << "거울아 거울아 누가 제일 예쁘니?"; return ins; } int main() { string answer; cin >> question >> answer; cout << "세상에서 제일 예쁜 사람은 " << answer << "입니다." << endl; 조작자 작성 조작자 사용 거울아 거울아 누가 제일 예쁘니?백설공주 세상에서 제일 예쁜 사람은 백설공주입니다.
Similar presentations