그냥 게임개발자

입력 본문

C++ 나만의 복습

입력

sudoju 2024. 3. 31. 17:11

어떤 코딩테스트 환경에서 입출력을 신경쓰지 않아도 되는 경우가 있지만

입출력을 신경써야 하는 경우도 있다.

 

그냥 해주면 될텐데 말이죠

입력 귀찮아

 

 

입력

대표적으로 cin과 scanf가 있다.

cin은 개행문자 직전까지 입력받음

cin

cin은 개행문자직전까지 입력을 받는다.

ex) '산토스 천재' 입력 => 입력받은 값 '산토스'

 

#include <stdio.h>

using namespace std;

string a;

int main()
{
    cin >> a;
    cout << a << "\n";
    return 0;
}

/*
입력 : 산토스 천재
출력 : 산토스
*/

 

개행문자를 넣어 2개의 문자열을 입력하면 또 상황이 달라진다.

 

#include <stdio.h>

using namespace std;

string a;
string b;

int main()
{
    cin >> a >> b;
    cout << a << "\n";
    cout << b << "\n";
    return 0;
}

/*
입력 : 산토스 천재
출력 : 산토스
      천재
*/

 

scanf

 

#include <stdio.h>

using namespace std;

int a;

int main()
{
    cin >> a;
    scanf("%d", &a);
    return 0;
}

 

scanf는 첫번째 매개변수로 인자를 받는 형식을 지정해서 입력을 받는다.

int scanf (const char* format, ...);

 

%d(decimal)는 int

%lf(longfloat)는 double

%c(character)는 char

 

#include <stdio.h>

using namespace std;

int a;
double b;
char c;

int main()
{
    scanf("%d %lf %c", &a, &b, &c);
    printf("%d\n", a);
    printf("%lf\n", b);
    printf("%c\n", c);
    
    return 0;
}

 

여기서 입력을

12345

123.45

a

 

이렇게 받게 되면

출력은

12345

123.45

a

이렇게 나온다.

 

scanf는 주로 입력형식이 까다롭거나 이 방식을 이용해야 할 때 사용하는게 좋고 그렇지 않다면 보통 cin으로 쓰는게 좋다.

 

scanf로 받을 수 있는 타입과 형식은 다음과 같다.

형식 타입
%d int
%c char
%s string
%lf double
%ld long long

 

그렇다면 scanf를 활요해 실수타입을 정수타입으로 받아보자.

 

#include <stdio.h>

using namespace std;

int a, b;
double c;

int main()
{
	scanf("%d.%d", &a, &b);
    printf("\n%d %d\n", a, b);
    
    scanf("%lf", &c);
    printf("%lf\n", c);
    
    return 0;
}

/*

입력
3.14
3.14

출력
3 14
3.140000

*/

 

 

실수 타입의 연산은 굉장히 까다롭기 때문에 사실 이런 트릭을 써서 정수타입의 기반의 연산을 유도하기도 한다.

 

 

getline

cin은 개행문자 직전까지 받는다고 이야기 했는데 혹시 기억이 나실라나?

 

안나면 다시 위를 올려보자.

 

 

기억 난다면 그렇다면 개행문자가 있어도 한꺼번에 받으려면 getline을 쓰면 된다.

 

#include <stdio.h>

using namespace std;

string s;

int main()
{
    getline(cin, s);
    cout << s << '\n';
    return 0;
}

/*

입력 : 산토스 최고
출력 : 산토스 최고

*/

 

진짜 잘됨 내가 해봤음

 

 

getline()은 개행 문자('\n')를 줄의 끝으로 인식하고 그 개행 문자직전까지 입력을 받는다.

그러니까 ' '이런 공백이 끝으로 인식하는 것이 아닌 개행문자('\n')가 와야 끝으로 입력을 받는다.

 

만약 다른 종결 문자를 사용하고 싶다면 이 또한 세번째 인자로 전달하면 된다.

getline(cin, s, '.');

이렇게 하면 .을 마지막으로 인식하고 입력을 받는다.

#include <stdio.h>

using namespace std;

int main()
{
    string s;
    getline(cin, s, '.');
    cout << s << '\n';
    
    return 0;
}

/*
입력 : 산토스 최고.
출력 : 산토스 최고
*/

 

 

 

getline 주의할 점

 

cin으로 N개의 getline을 받을지 설정하고 N개 만큼 getline의 입력이 들어오는 상황이 있다.

그럴 때 특정 문자열을 기반으로 버퍼 플래시를 하고 받아야 한다.

 

그니까 말이 좀 어렵게 느껴지겠지만 한마디로 그거다.

반복문을 통해서 입력 받을 수 있으니까 bufferflush를 해야 한다는 소리다.

보면 

for (int i = 0; i < N; ++i)
    getline(cin, s);

이런상황

그렇다면 여기서 cin은 \n까지 직접 입력을 반복하면서 받는데 그렇다면 중간에 개행문자가 남아있기 때문에 이 버퍼의 개행 문자를 없애주기 위해 getline(cin, bufferflush)를 해주어야 한다.

 

여기서 개행문자라는 것은 '\n'도 있지만 띄어쓰기(공백)도 포함이다.

 

#include <stdio.h>

using namespace std;

int N;
string s;

int main()
{
    cin >> N;
    string bufferFlush;
    getline(cin, bufferFlush);
    
    for (int i = 0; i < N; ++i)
    {
        getline(cin, s);
        cout << s << "\n";
    }
    
    return 0;
}

 

 

또 하나 살펴보자.

int n;
string str;
cin >> n;
getline(cin, str);

 

이 상황에서 첫번째 cin 입력에서 개행문자가 포함이 되어있다.

그렇기에 다음 getline을 실행하기 전에 이미 버퍼에 ('\n')가 그대로 남아있어 getline()에 들어가기 때문이다.

이를 해결하기 위해서는 cin.ignore()라는 함수를 사용한다.

 

int n;
string s;
cin >> n;
cin.ignore();
getline(cin, str);

 

이렇게 되면 cin.ignore()가 입력 버퍼의 모든 내용을 제거해주어 getline()이 정상적으로 작동한다.ㅇㅇ

 

 

입력 하나 쓰는데도 이렇게 오래걸리고 많네요 참..

 

그래도 지식 하나 늘었으니 행복하다.

'C++ 나만의 복습' 카테고리의 다른 글

타입? 타입변환?  (0) 2024.03.31
출력  (0) 2024.03.31
STL이란?  (1) 2024.03.31
define이란?  (0) 2024.03.31
typedef이란?  (0) 2024.03.31