출처: http://www.jungol.co.kr/bbs/board.php?bo_table=pbank&wr_id=1153&sca=9040
Approach
복호화 키는 공백을 포함하지 않으나 암호문은 공백을 포함하고 있다.
→ <stdio.h>에 포함된 fgets(문자열 이름, 문자열 길이, 입력 스트림)
하지만 fgets()는 개행문자('\r', '\n')도 입력한다는 점에 유의해야 한다.
윈도우의 개행문자('\r\n')와 리눅스의 개행문자('\n')가 다르기에
가령, 윈도우에서 만든 파일을 리눅스에 읽는 경우 두 개의 개행문자가 읽히는 문제가 발생
그렇기에 문자열 길이를 구할 때, 개행문자('\r', '\n')을 제거하여 구할 수 있다.
int strlen(char *s, int len = 0){
while(*s && *s != '\r' && *s != '\n') s++, len++;
*s = '\0';
return len;
}
strtok() 라이브러리 함수 이용
fgets(buf, 110, stdin);
strtok(buf, "\r\n"); // 첫 개행 문자에 널 문자를 넣는다.
#include <stdio.h>
char code[30], buf[100];
int strlen(char *s, int len = 0){
while(*s && *s != '\r' && *s != '\n') s++, len++;
*s = '\0';
return len;
}
inline int isupper(char c){ return c >= 'A' && c <= 'Z';}
inline int islower(char c){ return c >= 'a' && c <= 'z';}
int main(){
// freopen("input.txt", "r", stdin);
fgets(code, 30, stdin);
fgets(buf, 100, stdin);
int i, len = strlen(buf);
for(i=0; i<len; ++i){
char c = buf[i];
// 'A' = 65, 'a' = 97
if(isupper(c)) buf[i] = code[c-'A'] + 'A' - 'a';
else if(islower(c)) buf[i] = code[c-'a'];
}
puts(buf);
}
참고
Q. 복호화 키(code)는 공백을 포함하지 않으므로 scanf("%s", code);로 받아도 되지 않을까?
Q. 아래 코드에 "abc"와 "test"를 순서대로 입력하였을 때 어떤 문제가 발생할까?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
char code[30], buf[100];
int main() {
scanf("%s", code);
fgets(buf, 100, stdin);
printf("%s\n", code);
printf("%s\n", buf);
}
"abc" 입력 후 추가로 타이핑 입력하지 못하고 code와 buf가 출력되었습니다.
* scanf()는 개행('\n')을 처리하지 않습니다. 그렇기에 "abc\n"을 입력하였을 때,
"abc"만 처리되고 "\n"은 남아있어서 fgets() 해당 개행문자를 처리하고 끝난 것입니다.
물론 scanf()에서 '\n'이나 공백을 scanf("%s ") 혹은 scanf("%s\n")으로도 처리할 수 있으나
실제 문자열을 입력할 때 중간에 공백이나 개행문자가 더 있을 수 있으므로 안전하지 않다.
그렇기에 이 문제를 포함해서 fgets()를 연달아 사용하였습니다.
'PS 문제 풀이 > Jungol' 카테고리의 다른 글
[Jungol] 정올 1264 마법색종이 (0) | 2021.03.18 |
---|---|
[Jungol] 정올 4320 이진탐색 트리 (binary search tree) 2 (0) | 2021.03.18 |
[Jungol] 정올 1133 UNIQUENESS2 (0) | 2021.03.18 |
[Jungol] 정올 3699 변장 (0) | 2021.03.18 |
[Jungol] 정올 2518 문자열 변환 (0) | 2021.03.18 |
댓글