[전공]

[명품 C++] 11 C++ 입출력 시스템

danhan 2022. 6. 6. 20:31

출처 :

  • 명품 C++ Programming (저자 황기태)
  • 객체지향프로그래밍

스트림

  • 데이터의 흐름, 혹은 데이터를 전송하는 소프트웨어 모듈
  • 스트림의 양 끝은 프로그램과 장치 연결
  • 입출력 기본 단위 - 바이트

C++ 스트림 종류

  • 입력 스트림
  • 입력 장치, 네트워크, 파일 → 프로그램
  • 출력 스트림
  • 프로그램 → 출력장치, 네트워크, 파일

C++ 입출력 스트림 버퍼

  • 키 입력 스트림의 버퍼
    • 입력장치로부터 입력된 데이터를 프로그램으로 전달하기 전에 일시 저장
    • 키 입력 도중 수정 가능
    • <Enter> 키가 입력된 시점 부터 키 입력 버퍼에서 프로그램이 읽기 시작
  • 스크린 출력 스트림 버퍼
    • 프로그램에서 출력된 데이터를 출력 장치로 보내기 전에 일시 저장
    • 출력 장치를 반복적으로 사용하는 비효율성 개선
    • 버퍼가 꽉 차거나 강제 출력 명령(flush) 시에 출력 장치에 출력
  • C++ 프로그램이 실행될 때 자동으로 생겨나는 스트림
    • cin
    • cout
    • cerr
      • ostream타입 객체로 스크린과 연결
      • 오류 메시지를 출력할 목적
      • 오류를 바로 알리기 위해 스트림 내부 버퍼를 거치지 않고 추력
    • clog
      • ostream 타입 스트림 객체로 스크린과 연결
      • 오류 메시지를 출력할 목적
      • 스트림 내부 버퍼를 거쳐 출력

ostream 멤버 함수

// ch 문자를 스트림에 출력
ostream& put(char ch) 
// str 배열에 있는 n개의 문자를 스트림에 출력
ostream& writed(char * str, int n)
// 현재 스트림 버퍼에 있는 내용 강제 출력
ostream& flush()

istream 멤버 함수

// 입력 스트림에서 문자를 읽어 return 
// 오류나 EOF를 만나면 -1(EOF) return
int get()
// 입력 스트림에서 문자를 읽어 ch에 저장
// 현재 입력 스트림 객체(*this)의 참조 리턴
// 오류나 EOF를 만나면, 스트림 내부의 오류 플래그 세팅
istream& get(char & ch)
int ch;
while((ch = cin.get()) != EOF) { // EOF 는 -1
	cout.put(ch);                  // 읽은 문자 출력
	if(ch == '\\n')
		break;
}

char ch;
while(true) {
	cin.get(ch);         // 입력된 키를 ch에 저장하여 리턴
	if(cin.eof()) break; // EOF를 만나면 읽기 종료
		cout.put(ch);
	if(ch == '\\n')
		break;             // <Enter> 키가 입력되면 읽기 중단
}

get() 과 get(char&)을 이용한 한 줄의 문자 읽기

// cin.get()로 <Enter> 키까지 입력 받고 출력 
void get1() {
	int ch; // EOF와의 비교를 위해 int 타입으로 선언
	while((ch = cin.get()) != EOF) { // 문자 읽기. EOF 는 -1
		cout.put(ch); // 읽은 문자 출력
		if(ch == '\\n')
		break; // <Enter> 키가 입력되면 읽기 중단
	}
}

//cin.get(char&)로 <Enter> 키까지 입력 받고 출
void get2() {
	char ch;
	while(true) {
		cin.get(ch); // 문자 읽기
		if(cin.eof()) break; // EOF를 만나면 읽기 종료
			cout.put(ch); // ch의 문자 출력
		if(ch == '\\n')
			break; // <Enter> 키가 입력되면 읽기 중단
	}
}

문자열 입력

  • 입력 스트림으로부터 n-1개의 문자를 읽어 배열 s에 저장하고 마지막에 '\0'문자 삽입
  • 입력 도중 '\n'을 만나면 '\0'을 삽입하고 리턴
istream& get(char * s, int n);

// 최대 9개의 문자를 읽고 끝네 '\\0'을 붙여 str 배열 저장
char str[10];
cin.get(str, 10);
  • 입력 도중 ‘\n’을 만날 때 <Enter키> ‘\0’는 스트림 버퍼에 남아있음
  • 다시 get()으로 문자열 읽기를 시도하면 입력 스트림에 남은 ‘\n’를 만나 바로 리턴되는 무한 루프에 빠질 수 있음
  • 이를 위해 cin.get()이나 cin.ignor(1); 으로 ‘\n’을 스트림에서 그냥 읽어서 버려야한다.

istream& ignore(int n=1, int delim=EOF) 는 입력 스트림에서 n개 문자를 제거

get(char *, int)로 문자열 입력

char cmd[80];

while(true) {
	cout << "종료하려면 exit을 입력하세요 >> ";
	cin.get(cmd, 80); // 79개까지의 영어 문자 읽음.

	if(strcmp(cmd, "exit") == 0) {
		cout << "프로그램을 종료합니다....";
		return 0;
	} else
	  // 버퍼에 남아 있는 <Enter> 키 ('\\n') 제거
		// 안하면 스트림에 개행 문자가 그대로 남아있어 다음 입력이 \\nexit가 된다.
		cin.ignore(1);
}

한 줄 읽기

//입력 스트림으로부터 최대 n-1개의 문자를 읽어 배열 s에 저장하고 마지막에 '\\0' 삽입
// 입력도중 delim에 지정된 문자를 만나면 지금까지 읽은 문자를 배열 s에 저장하고 리턴
// 연속사용할 때 cin.get()이나 cin.ignore(1); 필요
istream& get(char * s, int n, char delim='\\n')
// get()과 동일하지만 delim에 지정된 구분 문자를 스트림에서 제거
istream& getline(char * s, int n, char delim='\\n')

입력 문자 건너 띄기와 문자 개수 알아내기

istream& ignore(int n=1, int delim=EOF)
int gcount()

포맷 입출력

  • 포맷 플래그
    • 입출력 스트림에서 입출력 형식을 지정하기 위한 플래그
    // flags를 스트림의 포맷 플래그로 설정하고 이전 플래그를 리턴한다.
    long setf(long flags)
    long unsetf(long flags)
    
  • 포맷 함수
  • int width(int minWidth) char fill(char cFill) int precision(int np)
  • 조작자 manipulator

조작자

  • << 나 >> 연산자와 함꼐 사용
  • 매개 변수 없는 조작자
cout << hex << showbase << 30 << endl;
cout << dec << showpos << 100 << endl;
  • 매개 변수 있는 조작자 #include <iomanip> 필요 (기출)

매개 변수 가진 조작자 이용

#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진수
	}
}

삽입 연산자 <<

  • << 연산자는 C++의 기본 연산자 - 정수 시프트 연산자

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;
	}
	// private x,y에 접근하기 위해 friend 선언
	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);
	cout << p << endl;     // Point 객체 화면 출력
	Point q(1,100), r(2,200);
	cout << q << r < endl; // Point 객체들 연속하여 화면 출력
}
#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 화면 출력
}