티스토리 뷰

simple I/0

각 언어마다 입출력을 할 때 장단점이 있는 듯하다. C++에서는 먼저 받아올 변수의 자료형을 선언하고, 공백을 활용하여 해당 변수에 맞는 자료형으로 할당할 수 있다. 변수의 자료형을 미리 선언하는 것 빼고는 Python과 달라 보이지 않고 오히려 불편한데, 여러 자료형을 한 번에 받아올 수 있다는 점은 반대로 장점이 된다. 두 코드를 통해 차이를 이해해 보자.
 

Python

# 받아올 자료형이 같을 때: 공백을 기준으로 나눠서 할당

a, b = map(int, input().split()) 

# 받아올 자료형이 다를 때: list로 받아온 후 자료형 변경
# ex) input: '사과 3'

arr = list(input().split())
b = int(arr[1])

자료형이 같을 때에는 map()을 통해 같은 자료형으로 변경해 주는 것이 가능하지만, 다양한 자료형을 받아 올 때에는 해당 자료형에 맞게 후처리를 해줘야 한다.
 

C++

#include <iostream>
using namespace std;

int main() {
	int x, z;
    string y;
    
    cin >> x >> y >> z;
    return 0;
}

이와 다르게 C++은 먼저 해당 변수의 자료형을 선언해줘야 하는 단점이 있지만, 한 번 선언을 해주면 공백이 있는 입력은 비교적 쉽게 받아올 수 있다.
 

cin, cin.fail()

그러면 원하는 자료형으로 입력받지 못했을 때에 에러처리를 어떻게 하면 좋을까? 이런 상황에서는 먼저 알아야 할 세 가지 개념이 있다. 첫 번째는 cin의 상태(Error states)이다. 해당 입력이 잘못되었는지 알기 위해서는 boolean 자료형을 반환하는 fail() 함수를 통해 판단하거나, 단순히 cin 자체만을 작성해도 된다.

#include <iostream>
using namespace std;

int main() {
	int a;
    cin >> a;
    
    // 첫번째 방법
    if (cin.fail()) {
    
    }
    
    // 두번째 방법
    if (!cin) {
    
    }
    return 0;
}

fail()은 에러가 났을 때 1을 반환하고 아닐 때 0을 반환하지만, cin은 정상일 때 1, 에러일 때 0을 반환한다. 헷갈리지 말자.
 

ignore(), clear()

이어서 우리가 제대로 된 값을 다시 입력받고 싶다면 두 가지 절차를 걸쳐야 할 것이다. 먼저 상태를 초기화시키고, 이미 버퍼에 넣어버린 값을 없애야 한다. 이때 필요한 것이 clear()와 igore()이다.
 먼저 clear()는 단순히 cin의 상태를 초기화해 주는 녀석이다. 정상적인 입력을 받을 때까지 반복문을 돌린다면, 다시 loop가 돌 수 있게 cin의 상태를 초기화해줘야 할 것이다. 여기서 짚고 넘어가야 할 중요한 사실은 'The clear method does NOT clear the buffer'라는 점. 이러한 이유로 ignore과 함께 설명하며 차이를 익히는 것이 중요하다.
 그렇다면 ignore()은 뭘까? 이미 메모리에 저장된 데이터 때문에 cin의 상태를 원래대로 돌리더라도 잘못된 데이터는 계속해서 에러를 발생시킨다. 이때, 어느 크기만큼 없앨지, 어느 문자를 만날 때까지 없앨지 이 두 가지 요소(해당 함수는 두 가지 parameter를 담는다.)중 하나라도 만족시킬 때까지 버퍼의 값을 무시해 주는 녀석이 바로 ignore()이다.
 

예시 코드 1

#include <iostream>
#include <climits>

using namespace std;

int main()
{
    int x;
    cout << "Enter the number: " << flush;
    cin >> x;
	
    // 입력이 정상적일 때까지
    while (!cin)
    {
        cout << "Invalid data type." << endl;
        
        // cin의 상태 초기화
        // '\n'를 만나거나 해당 버퍼가 담을 수 있는 최대 크기까지 무시
        cin.clear();
        cin.ignore(SSIZE_MAX, '\n');
        cout << "Enter the number: " << flush;
        cin >> x;
    }

    cout << "Entered number is " << x << endl;
    return 0;
}

해당 예시는 입력을 int형으로 받을 때까지 반복하고, 정상 상태라면 해당 int값을 출력하는 코드이다.
 

예시 코드 2

#include <iostream>
#include <cmath>
using namespace std;

double distance(double x1, double y1, double x2, double y2) {
	dx = x1 - x2;
    dy = y1 - y2;
    return sqrt(dx * dx + dy * dy;
}

int main()
{
    double px, py;
    cout << "Enter a point: " << flush;
    cin >> px >> py;

    double total_distance = 0;

    while (cin)
    {
        cout << "Enter a point: " << flush;
        double x, y;
        cin >> x >> y;
        if (cin)
            total_distance += distance(px, py, x, y);
        px = x;
        py = y;
    }
    cout << "Total distance is " << total_distance << endl;
    return 0;
}

해당 예시는 2차원 좌표(x, y)를 잘못된 입력이 나올 때까지 받으면서, 순차적으로 좌표간의 길이를 더해 합을 구하는 코드이다.
 
해당 코드들을 통해 clear, ignore, 그리고 간단한 입출력을 이해해보자.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함