[SW Expert Academy] 8741.두문자어



문제

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AW2y6n3qPXQDFATy&categoryId=AW2y6n3qPXQDFATy&categoryType=CODE





풀이

문제는 기초 문제인데, 두가지 자주 잊어버리는 내용에 대해 설명하고자 한다.

1. C++에서 공백이 포함된 문자열 여러개 받기

기본적으로 getline함수를 많이 이용한다. getline(cin, string, char) 형식으로 첫번째 인자에 cin을, 두번째 인자에 저장하려는 string 변수를, 세번째 인자에 입력을 종료하기 위해 입력하는 문자를 넣어준다. 세번째 인자는 비워두면 default로 '\n', 즉 엔터값이 들어간다. 
중요한 점은, 이전에 cin을 사용하여 입력을 받은 적이 있다면 무조건 cin.ignore() 를 이용해서 입력 버퍼를 비워줘야 한다. 비워주지 않으면 여러줄을 입력 받을 때 입력 받는 문자열을 담는 공간을 s[i]라고 한다면, s[0]에 엔터값이 들어가게 된다. 밑의 코드에서 설명하겠다.

2. 대문자를 소문자로, 소문자를 대문자로

C++의 toupper 또는 tolower를 이용하는 방법도 있지만, 그냥 char - 32를 하면 대문자로 바꿔주고, char + 32를 하면 소문자로 바꿔준다. char도 ASCII 코드 상으로 int형으로 표현할 수 있는데, 그걸 이용해준 것이다. 참고로 문자형 숫자, 즉 '0', '1', '2' 같은 것을 정수로 바꿔주고 싶으면 48을 빼주면 된다. ('1' - 48) 이는 문자 '0'이 48을 의미하기 때문에 '0' - 48 = 48 - 48 = 0 이 되기 때문이다.




//
//  SWEA8741.cpp
//  SCPC
//
//  Created by 신기열 on 28/10/2019.
//  Copyright © 2019 신기열. All rights reserved.
//

#include <iostream>
#include <vector>

using namespace std;

int main(){
    
    int n;
    cin >> n;
    vector<string> s;
    string str;
    
    cin.ignore();
    for(int i = 0; i < n; i++){
        getline(cin, str);
        s.push_back(str);
    }
    
    for(int i = 0; i < n; i++){
        string ans;
        ans = ans + (char)(s[i][0] - 32);
        int j = 1;
        while(j < s[i].size()){
            if(s[i][j] == ' '){
                j++;
                ans = ans + (char)(s[i][j] - 32);
            }
            j++;
        }
        cout << "#" << i + 1 << " " << ans << '\n';
    }
    
    return 0;
}


코드를 보면 위에서 n에 대한 입력을 받았는데, 이 때 n을 입력하고 엔터를 쳤기 때문에 버퍼에 '\n'이 남아 있는 상태이다. 따라서 cin.ignore()를 해줘야 현재 남아있는 엔터가 없어지고 문자열 한줄을 제대로 입력할 수 있게 된다.

댓글