PS/자주 하는 답변

문자열의 끝에는 항상 널 문자가 들어갑니다.

djm03178 2023. 1. 2. 01:08

C나 C++에서 char로 된 배열에 문자열의 형태로 입력을 받는 경우 가장 먼저 생각해야 할 것은 바로 널 문자 ('\0')입니다. 널 문자는 문자열의 끝을 알려주는 특별한 문자로, char 문자열에 대한 모든 문자열 관련 라이브러리는 널 문자를 통해 문자열의 끝을 인지합니다.

 

이는 입력이나 출력 시에도 예외가 아닙니다. 모든 char 문자열 입력 함수 (scanf, fgets, cin, getline 등)를 통해 char 문자열을 입력받으면 이 함수들은 자기가 알아서 문자열의 끝에 널 문자를 추가해줍니다. 그 말은 길이가 $N$인 문자열을 입력받는다면, 입력 함수들이 실제로 사용하는 배열의 크기는 $N+1$이라는 뜻입니다.

 

예를 들어, 문자열의 길이가 최대 100만인 문제에서 다음과 같이 입력을 받으면 배열의 길이를 넘어서게 됩니다.

char str[1000000];

cin >> str; // str[1000000] = '\0';
// 또는
scanf("%s", str); // str[1000000] = '\0';

올바르게 이 문자열을 저장하려면 배열의 크기는 최소 100만 1이어야 합니다.

char str[1000001];

cin >> str; // str[1000000] = '\0';
// 또는
scanf("%s", str); // str[1000000] = '\0';

예외적으로 fgets의 경우 여기에 추가적으로 매 줄의 끝에 있는 개행 문자까지 저장을 해줍니다. 따라서 이 개행 문자까지 올바르게 입력받기 위해서는 배열의 크기는 최소 100만 2이어야 합니다.

char str[1000002];

fgets(str, sizeof(str), stdin); // str[1000000] = '\n'; str[1000001] = '\0';

사실 이렇게 칼같이 배열의 크기를 딱 맞게 설정하는 것은 매우 스트레스이고 실수할 여지가 크기 때문에, 비단 문자열뿐만이 아니라 다른 종류의 배열들에 대해서도 그냥 매우 넉넉하게 설정하는 것을 추천드리는 바입니다.

char str[1000005];

이렇게 하면 마음이 편하지 않나요?