본문으로 건너뛰기

문자열

정보처리기사 목차프로그래밍 기초레슨 131 / 233

목차

문자열(string)은 글자를 차례로 늘어놓은 값입니다. C에는 문자열 자료형이 따로 없어, char 배열에 글자를 하나씩 넣고 끝에 널 문자(null character) '\0'을 붙여 문자열로 씁니다. 끝 표시가 있어야 글자가 어디까지인지 알 수 있기 때문입니다. 시험은 글자 수와 칸 수의 차이, 널 문자에서 멈추는 반복과 출력을 묻습니다. 아래 그림은 "OS"가 칸 셋에 들고, 글자를 세는 반복이 널 문자에서 멈추는 모습입니다.

10단계 중 1단계. 이 그림 읽는 법: 칸 하나에 글자 하나가 들고, 칸 위 수가 인덱스입니다. 4번 줄 — "OS"는 글자 둘이지만 끝에 널 문자 '\0'이 붙어 칸이 셋입니다.

1널 문자로 끝나는 char 배열

char s[] = "OS";는 칸 셋을 만들어 'O' · 'S' · '\0'을 넣습니다. 큰따옴표 문자열 끝에는 널 문자가 저절로 붙어, 칸 수는 글자 수 + 1입니다. 널 문자는 값이 0인 글자로, 문자열이 끝나는 자리를 알립니다.

식값까닭
sizeof s3칸 수(char 한 칸은 1바이트)
strlen(s)2널 문자 앞까지의 글자 수
s[2]'\0'끝 표시, 값 0

strlen은 <string.h>에 있는 함수입니다. 작은따옴표 'O'는 글자 하나이고, 큰따옴표 "O"는 'O'와 '\0' 두 칸입니다. char s[10] = "OS";처럼 칸이 남으면 남은 칸은 모두 '\0'으로 채워집니다.

2널 문자까지 읽는다 — %s와 반복

printf("%s", s)는 첫 칸부터 널 문자 앞까지 찍고, 글자를 다루는 반복도 while (s[i] != '\0')처럼 널 문자에서 멈춥니다. 그래서 가운데 칸에 '\0'을 넣으면 문자열이 거기서 끝납니다. "OS"에서 s[1] = '\0'; 뒤 %s는 O만 찍습니다.

글자 하나는 s[i]로 짚고 %c로 찍습니다. 글자는 정수이기도 해서, 소문자 'a'(97)에서 32를 빼면 대문자 'A'(65)가 됩니다(자료형과 형 변환).

예제

글자 l을 세고 가운데 칸에 널 문자를 넣는 코드입니다. 찍힐 값을 먼저 정해 보세요.

#include <stdio.h>

int main(void) {
  char s[] = "Hello";
  int i = 0, n = 0;
  while (s[i] != '\0') {
    if (s[i] == 'l') {
      n++;
    }
    i++;
  }
  s[2] = '\0';
  printf("%s %d\n", s, n);
  return 0;
}
실행 결과 보기
실행 결과
He 2

반복은 H · e · l · l · o를 지나 s[5]의 '\0'에서 멈추고, l이 둘이라 n은 2입니다. s[2]에 '\0'을 넣으면 문자열은 s[0] · s[1]의 He에서 끝나, %s는 He만 찍습니다. 뒤 칸의 l · o는 남아 있지만 찍히지 않습니다.

같은 코드를 Java·Python으로

CJavaPython
문자열char 배열 + '\0'Stringstr
길이strlen(s)s.length()len(s)
한 글자s[1]s.charAt(1)s[1]
한 글자 바꾸기s[1] = 'a'; 됨안 됨안 됨(TypeError)
잇기함수로(32단원)++
char 크기1바이트2바이트char 없음 — 길이 1인 str

Java·Python 문자열은 끝에 널 문자를 두지 않고 길이를 따로 압니다. 한 번 만든 문자열은 바꿀 수 없어 새 문자열을 만듭니다.

시험 포인트

  • 필기: C 문자열은 끝에 널 문자 '\0'이 붙어, 크기를 비운 char s[] = "…";는 칸 수가 글자 수 + 1입니다. sizeof는 바이트 수라 char 배열에서는 칸 수와 같고, strlen은 널 문자 앞까지의 글자 수입니다. %s와 문자열 반복은 널 문자에서 멈춥니다.
  • 실기: 출력을 그대로 씁니다. 가운데 칸에 '\0'을 넣으면 %s가 거기서 멈추는 것과, 32를 빼고 더하는 대소문자 바꾸기를 따라갑니다. 이름은 널 문자(Null Character), 글자 수를 돌려주는 함수는 strlen으로 씁니다.

확인 문제

1. char s[] = "DB2026";일 때 sizeof s와 strlen(s)의 값을 차례로 고르세요.

  • ① 6, 6
  • ② 7, 6
  • ③ 6, 7
  • ④ 7, 7
정답

②입니다. 글자가 여섯이고 끝에 널 문자가 붙어 칸은 일곱이며, strlen은 널 문자 앞까지 세어 6입니다.

  • ① 널 문자 칸을 빼고 칸 수를 셌습니다.
  • ③ 둘을 바꿨습니다. 칸 수가 글자 수보다 하나 많습니다.
  • ④ strlen은 널 문자를 세지 않습니다.

2. 예제 코드의 12번 줄에서 s[2]를 s[4]로 바꿨습니다. 출력을 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.

#include <stdio.h>

int main(void) {
  char s[] = "Hello";
  int i = 0, n = 0;
  while (s[i] != '\0') {
    if (s[i] == 'l') {
      n++;
    }
    i++;
  }
  s[4] = '\0';
  printf("%s %d\n", s, n);
  return 0;
}
정답

받는 답:

실행 결과
Hell 2

s[4]는 다섯째 칸 o입니다. 그 자리에 '\0'이 들어가 %s는 s[0]부터 s[3]까지 Hell을 찍습니다. n은 반복이 먼저 끝나 2 그대로입니다.

  • 틀리는 꼴 Hel 2: 인덱스를 1부터 세어 s[4]를 넷째 칸으로 봤습니다.
  • 틀리는 꼴 Hello 2: s[4]의 o가 '\0'으로 바뀌는 것을 놓쳤습니다. 대입은 그 칸의 글자를 바꾸고, %s는 '\0'에서 멈춥니다.

3. 다음 코드를 바퀴마다 줄여 적은 표입니다. (가)·(나)를 채운 뒤 출력을 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.

is[i]조건 s[i] >= 'a'바퀴가 끝난 뒤 s
0'a'참ABc
1'B'(가)ABc
2'c'참(나)
3'\0'반복 끝
#include <stdio.h>

int main(void) {
  char s[] = "aBc";
  int i = 0;
  while (s[i] != '\0') {
    if (s[i] >= 'a') {
      s[i] = s[i] - 32;
    }
    i++;
  }
  printf("%s\n", s);
  return 0;
}
정답

(가) 거짓 · (나) ABC이고, 출력은 다음과 같습니다.

실행 결과
ABC

'B'는 66이라 'a'(97)보다 작아 그대로 두고, 소문자 'a' · 'c'만 32를 빼 대문자가 됩니다.

  • 틀리는 꼴 ABc: 마지막 칸 'c'를 놓쳤거나, 대문자 B에서 반복이 멈춘다고 봤습니다. if가 거짓이어도 반복은 다음 칸으로 가고, '\0'을 만나는 i가 3일 때 끝납니다.

4. 다음 코드의 출력을 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.

#include <stdio.h>

int main(void) {
  char s[] = "abcde", t;
  int i = 0, j = sizeof s - 2;
  while (i < j) {
    t = s[i];
    s[i] = s[j];
    s[j] = t;
    i++;
    j--;
  }
  printf("%s %d\n", s, i);
  return 0;
}
정답

받는 답:

실행 결과
edcba 2

4번 줄은 char 배열 s와 char 변수 t를 함께 만듭니다. sizeof s는 널 문자까지 6칸이라 j는 4, 마지막 글자 e의 인덱스입니다. i와 j가 양 끝에서 다가오며 (0, 4) · (1, 3) 칸을 맞바꾸고, i와 j가 둘 다 2가 되면 2 < 2가 거짓이라 멈춥니다. 가운데 c는 그대로입니다.

  • 틀리는 꼴 dcbae 2: sizeof s를 글자 수 5로 보아 j를 3에서 시작했습니다. sizeof는 널 문자 칸까지 세어 6입니다.
  • 틀리는 꼴 edcba 3: i와 j가 2일 때도 한 바퀴 더 돈다고 봤습니다. 2 < 2는 거짓이라 i는 2에서 멈춥니다.

5. 다음 (가)·(나)를 쓰세요. (가)는 한글 이름과 영문으로, (나)는 C 함수 이름 그대로 씁니다. 답을 끝까지 쓴 뒤 정답을 펼치세요.

  • (가) "DB"를 char 배열에 넣으면 'D' · 'B' 다음 칸에 저절로 들어가, 글자가 여기서 끝났음을 알리는 값 0의 글자
  • (나) <string.h>에 있으며, 그 값 0의 글자 앞까지 글자가 몇 개인지 돌려주는 함수
정답

받는 답: (가) 널 문자(Null Character) · (나) strlen

(가)는 '끝에 저절로 들어가는 값 0', (나)는 '그 앞까지 센 글자 수'가 실마리입니다.

  • 같은 이름의 다른 꼴: '\0'만 쓴 꼴 — 코드에 쓰는 꼴입니다. 이름을 물었으니 널 문자(Null Character)로 씁니다.
  • 틀리는 꼴 sizeof — (나)에: 함수가 아니라 연산자이고, 널 문자 칸까지 센 바이트 수(char 배열은 칸 수)를 냅니다.

처음이라면: C 언어 과목(준비 중)의 '문자열은 널 문자로 끝나는 char 배열' · 'strlen · strcpy · strcat · strcmp' 레슨에서 같은 규칙을 처음부터 천천히 봅니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

정보처리기사 목차로