본문 바로가기
C++

C++ 입력 & 출력

by FraisGout 2020. 7. 6.

C++ 입출력

C++C언어와 마찬가지로 입출력에 관한 기능을 언어에서 기본적으로 제공하지 않습니다.

 

그 이유는 컴파일러를 만들 때 입출력 기능을 해당 하드웨어에 가장 적합한 형태로 만들 수 있도록 컴파일러 개발자에게 권한을 주기 위해서입니다.

 

 

 

하지만 대부분의 C++ 컴파일러는 iostreamfstream 헤더 파일에 정의되어 있는 클래스 라이브러리를 제공합니다.

 

iostreamfstream 클래스 라이브러리의 중요 개념 중 하나가 바로 스트림(stream)입니다.

 

스트림(stream)

C++ 프로그램은 파일이나 콘솔의 입출력을 직접 다루지 않고, 스트림(stream)이라는 흐름을 통해 다룹니다.

 

스트림(stream)이란 실제의 입력이나 출력이 표현된 데이터의 이상화된 흐름을 의미합니다.

 

, 스트림은 운영체제에 의해 생성되는 가상의 연결 고리를 의미하며, 중간 매개자 역할을 합니다.

 

버퍼(buffer)

스트림은 내부에 버퍼(buffer)라는 임시 메모리 공간을 가지고 있습니다.

 

이러한 버퍼를 이용하면 입력과 출력을 좀 더 효율적으로 처리할 수 있게 됩니다.

 

버퍼를 사용하면서 얻을 수 있는 장점은 다음과 같습니다.

 

 

 

1. 문자를 하나씩 전달하는 것이 아닌 묶어서 한 번에 전달하므로, 전송 시간이 적게 걸려 성능이 향상됩니다.

 

2. 사용자가 문자를 잘못 입력했을 경우 수정을 할 수가 있습니다.

 

 

 

하지만 입력 작업에 버퍼를 사용하는 것이 반드시 좋은 것만은 아닙니다.

 

빠른 반응이 요구되는 게임과 같은 프로그램에서는 키를 누르는 즉시 바로 전달되어야만 합니다.

 

 

 

이렇게 버퍼를 사용하는 입력과 버퍼를 사용하지 않는 입력은 서로 다른 용도로 사용됩니다.

 

따라서 자신의 목적에 맞게 버퍼의 사용 여부를 판단해야 합니다.

 

대부분의 C++ 프로그램은 입력 시에는 사용자가 Enter 키를 누르면 입력 버퍼를 비우고, 출력 시에는 개행 문자를 전달받으면 출력 버퍼를 비우게 됩니다.

 

파일(file)이란?

파일(file)이란 의미 있는 정보를 담고 있으며, 이름을 가지고 있는 저장 장치상의 논리적인 단위를 의미합니다.

 

C++은 이러한 파일을 바이트별로 따로 읽을 수 있는 연속적인 바이트의 집합으로 취급합니다.

 

파일의 종류

컴퓨터는 파일을 다음과 같이 두 가지 종류로 나누어서 다룹니다.

 

 

 

1. 바이너리 파일(binary file)

 

2. 텍스트 파일(text file)

 

 

 

바이너리 파일은 데이터의 저장과 처리를 목적으로 01의 이진 형식으로 인코딩된 파일을 가리킵니다.

 

프로그램이 이 파일의 데이터를 읽거나 쓸 때는 데이터의 어떠한 변환도 일어나지 않습니다.

 

 

 

텍스트 파일은 사람이 알아볼 수 있는 문자열로 이루어진 파일을 가리킵니다.

 

프로그램이 이 파일의 데이터를 읽거나 쓸 때는 포맷 형식에 따라 데이터의 변환이 일어납니다.

 

C++ 파일 입출력 클래스

C++에서는 파일의 입출력을 표준 입출력처럼 처리합니다.

 

C++ 표준 입출력은 iostream 헤더 파일의 istream 클래스와 ostream 클래스의 멤버 함수로 처리합니다.

 

 

 

이와 마찬가지로 C++ 파일 입출력은 fstream 헤더 파일의 클래스 라이브러리를 가지고 처리하게 됩니다.

 

파일의 입력은 ifstream 클래스로, 파일의 출력은 ofstream 클래스의 멤버 함수로 처리합니다.

 

이 클래스는 iostream 헤더 파일의 클래스로부터 파생된 클래스입니다.

 

파일의 입출력

C++에서 파일에 대한 입출력 동작은 다음과 같은 순서에 따라 진행됩니다.

 

 

 

1. 스트림을 관리하기 위한 ifstream(또는 ofstream) 객체를 생성

 

2. 특정 파일과의 연결

 

3. cin 객체나 cout 객체와 같은 방법으로 객체를 사용하여 입출력 수행

 

4. 모든 작업이 끝나면 파일과의 연결 종료

 

 

 

특정 파일과의 연결은 open() 멤버 함수를 사용하여 다음과 같이 수행합니다.

 

예제

ifstream ifs; // ifs라는 ifstream 객체를 생성함.

 

ifs.open("example.txt"); // ifsexample.txt와 연결함.

 

 

 

위에서 살펴본 ifstream 객체의 생성과 파일과의 연결을 다음과 같이 한 줄로 결합할 수도 있습니다.

 

예제

ifstream ifs("example.txt"); // ifs라는 ifstream 객체를 생성하고, example.txt와 연결함.

 

 

 

이렇게 연결된 파일에서 cin 객체를 사용하는 방법과 동일한 방법으로 파일의 내용을 읽을 수 있습니다.

 

예제

char ch;

 

char buf[20];

 

string str;

 

ifs >> ch; // example.txt 파일에서 한 문자를 읽어 변수 ch에 저장함.

 

ifs.getline(buf, 20); // example.txt 파일에서 한 행을 읽어 배열 buf에 저장함.

 

getline(ifs, str); // example.txt 파일에서 한 행을 읽어 문자열 객체인 str에 저장함.

 

 

 

앞서 생성한 입출력 파일 스트림 객체의 수명이 다 하면 파일은 자동으로 닫힙니다.

 

또한, close() 멤버 함수를 통해 명시적으로 파일과의 연결을 닫을 수도 있습니다.

 

예제

ifs.close(); // 파일과의 연결을 닫음.

 

스트림의 상태 검사

C++의 파일 입출력 클래스는 스트림의 상태를 검사해주는 ios_base 클래스의 멤버 함수를 상속받습니다.

 

 

 

과거의 C++에서는 파일을 성공적으로 열었는지를 다음과 같은 방법으로 확인했습니다.

 

예제

1. if (ifs.fail()) { ... } // 파일을 여는데 실패한 경우

 

2. if (!ifs.good()) { ... } // 파일을 여는데 실패한 경우

 

3. if (!ifs) { ... } // 파일을 여는데 실패한 경우

 

 

 

최신의 C++에서는 파일의 성공적인 개방을 is_open 멤버 함수를 통해 확인할 수도 있습니다.

 

예제

if (!ifs.is_open()) { ... } // 파일을 여는데 실패한 경우

 

 

 

다음 예제는 C++에서 단순히 파일을 열어 그 안에 저장된 텍스트 한 줄을 읽어 오는 예제입니다.

 

예제

#include <iostream>

 

#include <fstream>

 

#include <string>

 

using namespace std;

 

 

 

int main()

 

{

 

ifstream ifs;

 

string str;

 

 

 

ifs.open("example.txt"); // "C++ 프로그래밍"

 

if(!ifs.is_open())

 

{

 

cout << "파일을 열 수가 없습니다!" << endl;

 

exit(1);

 

}

 

else

 

{

 

cout << "파일을 성공적으로 열었습니다!" << endl;

 

getline(ifs, str);

 

cout << str << endl;

 

ifs.close();

 

}

 

}

 

 

 

파일 모드

C++에서 파일 모드란 파일의 사용 용도와 파일의 데이터를 어떤 방식으로 입출력할지를 결정하는 상수입니다.

 

파일 모드 상수는 ifstream(또는 ofstream) 객체를 파일의 이름으로 초기화하거나, open() 멤버 함수를 통해 스트림에 파일을 연결할 때 파일 모드를 지정하기 위한 두 번째 매개변수로 사용됩니다.

 

 

 

예제

// ifs라는 ifstream 객체를 생성하고, example.txt와 읽기 모드로 연결함.

 

ifstream ifs("example.txt", ios_base::in);

 

 

 

기본적으로 ifstream의 생성자와 open() 멤버 함수는 파일 모드의 디폴트 인수로 ios_base::in을 제공합니다.

 

또한, ofstream의 생성자와 open() 멤버 함수는 파일 모드의 디폴트 인수로 ios_base::out | ios_base::trunc을 제공합니다.

 

C++ 파일 모드 상수

C++에서 제공하는 파일 모드 상수는 다음과 같습니다.

 

파일 모드 상수

설명

ios_base::in

파일을 오로지 읽는 것만 가능한 모드로 개방함.

ios_base::out

파일을 쓰는 것만이 가능한 모드로 개방함.

ios_base::ate

파일을 개방할 때 파일의 끝으로 파일 포인터를 이동시킴.

ios_base::app

해당 파일의 맨 끝에서부터 데이터를 추가함.

ios_base::trunc

파일이 있으면 해당 파일의 모든 데이터를 지우고 개방함.

ios_base::binary

바이너리 모드로 개방함.

 

 

이렇게 제공되는 파일 모드 상수는 단독으로 사용할 수도 있고, 여러 모드를 조합하여 사용할 수도 있습니다.

 

 

 

C++에서 자주 사용되는 파일 모드 조합은 다음과 같습니다.

 

파일 모드 상수

C언어 파일 모드

설명

ios_base::out | ios_base::trunc

"w"

파일을 쓰는 것만이 가능한 모드로 개방함.파일이 없으면 새 파일을 만들고,파일이 있으면 해당 파일의 모든 데이터를 지우고 개방함.

ios_base::out | ios_base::app

"a"

파일을 쓰는 것만이 가능한 모드로 개방함.

파일이 없으면 새 파일을 만들고,

파일이 있으면 해당 파일의 맨 끝에서부터 데이터를 추가함.

ios_base::in | ios_base::out

"r+"

파일을 읽고 쓰는 것이 둘 다 가능한 모드로 개방함.

ios_base::in | ios_base::out | ios_base::trunc

"w+"

파일을 읽고 쓰는 것이 둘 다 가능한 모드로 개방함.

파일이 없으면 새 파일을 만들고,

파일이 있으면 해당 파일의 모든 데이터를 지우고 개방함.

 

 

'C++' 카테고리의 다른 글

C++ 예외처리  (0) 2020.07.06
C++ STL알고리즘  (0) 2020.07.05
C++ STL컨테이너  (0) 2020.07.05
C++ STL반복자  (0) 2020.07.05
C++ 템플릿  (0) 2020.07.05

댓글