c++에서 string 입력받기

이 문제에서 처럼, 공백이 포함된 한 줄 전체를 string에 받아올 일이 있을때는 아래처럼 getline을 쓰면 된다.

1
2
string str;
getline(cin, str);
cs

 

c++로 입출력하기

앞에거는 printf,scanf랑 페어링 끄기, 뒤에거는 입출력반복될때 처리에 대한것

1
ios::sync_with_stdio(0);cin.tie(0);
cs

이거 하고 나면 printf, scanf쓰면 안된다.

헤더파일 단순화 하기

알고리즘 문제를 풀다보면 다음과 같이 헤더파일이 점점 길어지고 지저분해짐을 알 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <set>
#include <stack>
#include <queue>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <map>
 
using namespace std;
 
int dp[2][1000000+1];
int main(void)
{
cs

 

그 이유는 매번 문제마다 필요한 vector, map, string등을 그때 그때 추가하다보면 귀찮아서져 그냥 슈퍼셋으로 들고가게 되는 현상이 나타난다(...)

 

근데 gcc에서만 지원하긴하지만 다음처럼 <bits/stdc++h>를 쓰면 헤더파일이 무척 깔끔해진다. 자주쓰는 헤더들을 모아서 처리해주는 역할을 해주기 때문이다.

 

1
2
3
4
5
6
7
#include <bits/stdc++.h>
using namespace std;
 
int main(void)
{
    return 0;
}
cs

 

표준은 아니라서 visual c++나 xcode에서는 잘 안되는데,

xcode 기반의 clion을 쓰는 내 경우는 여기 링크에 나온대로 stdc++.h파일을 복사한다음에 다음경로에 설정해주니 잘 되었다.

만약에 bits/stdc++.h의 경로를 못찾겠다고 나오면,

CMakeLists.txt를 열어서 다음 부분을 추가해주면 되었다(include_directories 부분)

 

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1

mac에서 그냥 c++을 쓰는경우 (visual studio code등에서 사용) 다음 경로에 설정해주면 된다.

 

/usr/local/include

 

visual studio를 쓰는 경우는 아래 링크에 복사

 

D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include

 

그래프 그려주는 툴

https://csacademy.com/app/graph_editor/ 정말 짱인거 같다.

 

stl을 printf-style로 디버깅하기

visual studio가 라인디버깅 성능이 막강하긴 하지만, PS를 하다가 그렇게 하다보면 시간이 너무 많이 흘러가게 된다.

따라서 간단하게 vector나 map등을 print로 찍어보면 좋은데, built-in으로는 그러한 함수가 없고 반드시 루프를 돌려야 한다.

여기 있는 헤더를 include하면 그러한 점을 보완해준다.

 

간단하게 사용법을 보려면 다음 예제를 보자.

1
2
3
4
5
6
7
8
9
#include <bits/stdc++.h>
#include "dbg.h"  // https://github.com/sharkdp/dbg-macro
using namespace std;
int main()
{
    map<intstring> m = { {1,"abc"}, {2,"cde"} };
    dbg(m);
    return 0;
}
cs

 

dbg()로 감싸주기만 하면 그내용을 다음처럼 출력해준다.

1
[..\nothing\nothing.cpp:7 (main)] m = {{1"abc"}, {2"cde"}}
cs

 

물론 온라인저지에 이대로 제출할수는 없기 때문에(커스텀 헤더라, 저지 서버에서는 인식못하고, 속도도 떨어뜨릴거고)

다음과 같이 감싸주는 부분이 필요하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <bits/stdc++.h>
using namespace std;
#ifdef WIN32
#include "dbg.h"  // https://github.com/sharkdp/dbg-macro
#else
#define dbg(...)
#endif
int main()
{
    map<intstring> m = { {1,"abc"}, {2,"cde"} };
    dbg(m);
    return 0;
}
cs

 

나는 간단하게 WIN32으로 감싸주었지만, 좀 더 고민해서 잘 감싸는게 필요할지도 (-DONLINE_JUDGE등 사용)

 

 

입력개수가 명시되지 않은 입력을 받는법

예를 들어 이 문제의 경우 입력개수 없이 받도록 되어 있다. 

while(cin << n) 이렇게 받는걸로 추천되어 있다.

c스타일로 받을경우는 다음처럼 하면 된다.

1
2
3
4
int n;
while(scanf("%d"&n)!=EOF){
    //do something
}
cs

이 문제에서 연습할 수 있다.

 

freopen 사용하기

백준에서는 ONLINE_JUDGE를 define하고 있으므로 다음과 같이 사용하면 파일로 입력을 줄 수 있다.

1
2
3
#ifndef ONLINE_JUDGE
    freopen("input.txt""rt", stdin);
#endif
cs

 

char를 입력받는 방법

이 문제를 보면 숫자를 입력받은 다음에 char를 입력받게 되어 있는데 생각없이 scanf("%d") 한다음에 scanf("%c")를 하게 되면 \n char 때문에 제대로 안된다. 방법은 scanf("%c") 대신에 scanf("\n%c")로 해주면 되긴했다.

또는 숫자는 scanf("%d") 로 받고 그다음은 scanf("%s")로 문자열로 받아서 문자열 파싱을 해도 됨

 

EOF까지 입력받기

이 문제와 같이 N이주어지는게 아니라 단순히 EOF까지 입력을 받으라는 경우가 있다.

이때는 C언어의 경우는 다음처럼 scanf의 리턴값이 EOF임을 체크하면 된다.

#include <cstdio>

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        // process the input
    }
    return 0;
}

 

개행문자까지 문자열을 읽는 방법

3 @ %
10.4 # % @
8 #

위와 같이 어쩔때는 문자가 2개 (@ X), 어쩔때는 문자가 3개 (# % @), 어쩔때는 문자가 한개(#) 주어질때,

아래처럼 %[^\n]를 쓰면 개행문자까지 문자열을 읽을 수가 있다.

double A;
char s[10] = {};
scanf("%lf %[^\n]", &A, s);
for (int i = 0; s[i] != '\0'; ++i) {
    if (s[i] == '@') A *= 3;
    else if (s[i] == '%') A += 5;
    else if (s[i] == '#') A -= 7;
}

이 문제를 참조하자.

반응형

'Programming > Problem Solving' 카테고리의 다른 글

C++ bigint class  (0) 2020.03.30
백준 9663번 N-Queen  (0) 2020.03.15
행렬코딩  (0) 2020.03.01
C언어에서 표준입력으로 string 입력 받기  (0) 2020.02.21
백준 제출시 오류유형 정리  (0) 2019.03.18

+ Recent posts