https://www.acmicpc.net/problem/2908
C언어로 문자열 다루기는 정말 까다롭다.
출제 의도를 따르면 문자열로 푸는 것이 맞다. 그래서 당연히 나는 문자열로 풀었다.
그런데 다 풀고 검색해보니 그냥 정수로 푼 사람들도 많았다. 하지만 후회하지 않아!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int change_n_convert(char s[])
{
char tmp;
int ret;
tmp = s[2];
s[2] = s[0];
s[0] = tmp;
ret = atoi(s);
return (ret);
}
int main(void)
{
char s[7] = {
0,
};
int a = 0;
int b = 0;
scanf("%[^\n]s", s);
char *ptr = strtok(s, " ");
while (ptr != NULL)
{
if (a == 0)
a = change_n_convert(ptr);
else
b = change_n_convert(ptr);
ptr = strtok(NULL, " ");
}
if (a > b)
printf("%d", a);
else
printf("%d", b);
return (0);
}
s
에 공백을 포함한 문자열을 한 번에 scanf
로 받고strtok
함수를 이용해 문자열을 공백 기준으로 자른다.a
에 아무 값이 안 들어와있다면 change_n_convert
함수로 들어가 첫번째 수와 마지막 수의 자리를 바꾸고, atoi
함수를 이용해 문자열을 정수로 반환한 후 그 값을 리턴한다.a
가 0
이 아니라면 b
만 비어있을 것이기에 b
에 동일하게 change_n_convert
함수를 적용해준다.a
가 b
보다 크면 a
를, 아니면 b
를 출력해준다.scanf 함수의 형식 지정자를 보면 []
를 사용하여 입력된 정보를 구분하는 기준 문자를 변경할 수 있다. 예를 들어, 입력된 정보를 공백 문자나 탭 문자 또는 줄바꿈 문자가 아닌 a
로 구분하고 싶다면 아래와 같이 사용하면 된다. 즉, ^
문자 뒤에 자신이 입력 값을 구분할 때 사용할 문자를 적어주면 된다.
scanf("%[^a]s", str); // 사용자가 입력한 값을 'a' 문자로 구분한다.
풀이에서 나는 공백을 그대로 읽기 원했기 때문에 문제에서 주어지는 입력에 따라 개행 문자를 입력된 정보를 구분하는 기준 문자로 설정해줬다.
scanf("%[^\n]s", s); // 풀이에서 내가 사용한 방식
string.h
헤더 파일에 선언되어 있는 함수로, 특정 문자를 기준으로 문자열을 잘라주는 함수이다.
char *strtok(char *_String, char const *_Delimiter);
자른 문자열을 반환하고, 더 이상 자를 문자열이 없으면 NULL
을 반환한다.
strtok
함수는 지정된 문자를 기준으로 문자열을 자른다. 즉, strtok(s1, " ");
와 같이 " "(공백 문자)
를 넣어주면 공백으로 구분하여 문자열을 자른다 (단, 기준 문자를 ' '로 묶으면 안 된다). 특히 strtok
함수는 잘린 문자열을 한 번에 얻을 수 없어서 while
반복문으로 문자열을 계속 자르다가 문자열이 나오지 않으면 반복문을 끝내는 방식으로 사용한다.
char *ptr = strtok(s1, " "); // " " 공백 문자를 기준으로 문자열을 자름, 포인터 반환
while (ptr != NULL) // 자른 문자열이 나오지 않을 때까지 반복
{
printf("%s\n", ptr); // 자른 문자열 출력
ptr = strtok(NULL, " "); // 다음 문자열을 잘라서 포인터를 반환
}
여기서 포인트는 처음에 문자열을 자르고 다음으로 넘어갈 때는 strtok
의 첫 번째 인자로 NULL
을 줘야한다는 것이다. 이 이유는 strtok
의 작동 원리에 있다. strtok
는 자를 문자열 부분에 NULL
을 넣어준다. 그러므로 첫 인자에 NULL
을 넣어줘야 직전 strtok
함수에서 처리했던 문자열에서 잘린 문자열만큼 다음 문자로 이동한 뒤 다음 문자열을 자를 수 있는 것이다. 그렇게 처음에만 문자열을 첫 인자로 받고 이후에는 NULL
을 받다가, 문자열의 끝을 만나게 되면 그만 잘라야하기 때문에 while문의 조건을 ptr != NULL 로 걸어준다.
문자열을 새로 생성해서 반환하는 것이 아니라 원본 문자열의 내용을 바꾸기 때문에 조심하기!
📚 참고
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=tipsware&logNo=221261284797
https://dojang.io/mod/page/view.php?id=376