이 페이지의 목차
문자열 다루기
코드 예제: Python · C · 예상 50분
학습 목표
- 문자열을 자르고 잇고 찾는 방법을 설명한다.
- 문자열을 가공하는 프로그램을 작성한다.
관련 성취기준
- 프그02-01
변수와 자료형의 개념과 특징을 이해하고, 구분하여 지정할 수 있으며, 이들을 사용한 프로그램을 작성할 수 있다.
생각 열기 — 주민등록번호에서 생일만
060315-3000000 이라는 문자열이 있다. 여기서 생년월일 060315 만 꺼내려면 어떻게 해야 할까.
눈으로는 “앞에서 여섯 글자”라고 바로 말할 수 있다. 그런데 프로그램에게 시키려면 몇 번째부터 몇 번째까지인지 숫자로 말해 주어야 한다.
문자열은 글자가 순서대로 늘어선 것
문자열(string) — 글자가 순서대로 늘어선 값은 글자를 순서대로 늘어놓은 값이다. 순서가 있으므로 몇 번째 글자를 가리킬 수 있다. 그 번호를 인덱스(index) — 문자열이나 목록에서 몇 번째인지 가리키는 번호. 0부터 센다라 한다.
프 로 그 래 밍
0 1 2 3 4 ← 앞에서 셀 때
-5 -4 -3 -2 -1 ← 뒤에서 셀 때 (Python)
말 = "프로그래밍"
print("길이:", len(말))
print("첫 글자:", 말[0])
print("마지막 글자:", 말[-1])
print("앞 세 글자:", 말[0:3])
번호 = "060315-3000000"
print("생년월일:", 번호[0:6])
print("연도 앞자리 판단용 숫자:", 번호[7])길이: 5 첫 글자: 프 마지막 글자: 밍 앞 세 글자: 프로그 생년월일: 060315 연도 앞자리 판단용 숫자: 3
#include <stdio.h>
#include <string.h>
int main(void)
{
char word[] = "programming";
printf("길이: %zu\n", strlen(word));
printf("첫 글자: %c\n", word[0]);
printf("마지막 글자: %c\n", word[strlen(word) - 1]);
char id[] = "060315-3000000";
char birth[7];
strncpy(birth, id, 6);
birth[6] = '\0';
printf("생년월일: %s\n", birth);
printf("연도 앞자리 판단용 숫자: %c\n", id[7]);
return 0;
}길이: 11 첫 글자: p 마지막 글자: g 생년월일: 060315 연도 앞자리 판단용 숫자: 3
슬라이싱 — 잘라 내기
Python의 말[0:3] 처럼 범위로 잘라 내는 것을 슬라이싱(slicing) — 문자열이나 목록에서 정해진 범위만 잘라 내는 일이라 한다. 규칙 하나만 기억하면 된다.
시작 번호는 포함하고, 끝 번호는 포함하지 않는다.
[0:3] 은 0, 1, 2번째 세 글자다. 3번째는 들어가지 않는다. 어색해 보이지만 이 규칙 덕분에 끝 번호 − 시작 번호 = 개수가 되어 계산이 쉬워진다. [0:6] 은 정확히 여섯 글자다.
C의 문자열은 문자 배열이다
C에는 문자열 자료형이 따로 없다. 문자를 늘어놓은 배열이 문자열 노릇을 한다. 그래서 두 가지가 따라온다.
| 하려는 일 | Python | C |
|---|---|---|
| 길이 재기 | len(말) | strlen(word) — <string.h> 필요 |
| 글자 하나 | 말[0] | word[0] |
| 잘라 내기 | 말[0:6] | strncpy 로 옮기고 끝에 \0 을 넣는다 |
| 이어 붙이기 | a + b | strcat |
| 끝을 아는 법 | 길이를 스스로 안다 | 널 문자 \0 이 나올 때까지 |
널 문자(null character) — C에서 문자열의 끝을 알리는 값 0. 글자로는 보이지 않는다는 C 문자열의 핵심이다. 배열 자체는 자기 길이를 모르므로, 어디까지가 문자열인지 표시가 필요하다. strncpy 로 여섯 글자를 옮긴 뒤 birth[6] = '\0'; 을 적은 것이 그 표시다.
한글은 글자 수와 바이트 수가 다르다
위 두 예제의 결과를 견줘 보자. Python은 "프로그래밍" 의 길이를 5라고 했고, C는 "programming" 의 길이를 11이라고 했다. 영문이라 같아 보이지만, C에서 한글을 담으면 사정이 달라진다.
- Python의
len("프로그래밍")→ 5 (글자 수) - C의
strlen("프로그래밍")→ 15 (UTF-8에서 한글 한 글자가 3바이트)
그래서 C 예제에서는 한글 대신 영문 단어를 썼다. C에서 한글을 글자 단위로 자르려면 바이트를 직접 세거나 별도 처리가 필요하다.
활동
주민등록번호 형식 문자열에서 생년월일만 뽑기
약 20분1단계 — 인덱스 표를 채운다 (5분)
"060315-3000000" 의 각 자리 번호를 적어 본다.
| 글자 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| 0 | 6 | 0 | 3 | 1 | 5 | - | 3 |
- 하이픈(
-)은 몇 번인가? - 뒷자리 첫 숫자는 몇 번인가?
2단계 — 잘라 낸다 (10분)
실행기의 [고치기]로 아래를 하나씩 확인한다. 예상을 먼저 적는다.
| 식 | 내 예상 | 실제 결과 |
|---|---|---|
번호[0:2] (연도 두 자리) |
||
번호[2:4] (월) |
||
번호[4:6] (일) |
||
번호[7:] (뒷자리 전부) |
||
번호[:6] (앞 여섯 글자) |
||
번호[-7:] (뒤에서 일곱 글자) |
3단계 — 보기 좋게 만든다 (5분)
060315 를 2006년 3월 15일 처럼 바꿔 출력하는 코드를 만들어 보자.
- 연도 앞에
20을 붙이려면 문자열을 이어 붙이면 될까, 숫자로 바꿔 계산해야 할까? 03월을3월로 만들려면 무엇을 해야 하는가? (int("03")을 해 보자)
개인정보 주의 — 실제 주민등록번호를 쓰지 않는다. 이 활동의 값처럼 지어낸 숫자만 쓴다. 1단원 9차시에서 다룬 규칙이다.
개념 확인 문제
보기를 누르면 바로 채점된다. 틀려도 해설을 읽으면 된다.
Python에서 말 = 「프로그래밍」 일 때 말[1] 은?프그02-01
번호[0:6] 이 정확히 여섯 글자가 되는 까닭은?프그02-01
C에서 문자열의 끝을 알리는 것은?프그02-01
Python의 len(「프로그래밍」) 과 C의 strlen(「프로그래밍」) 결과가 다른 까닭은?프그02-01
길이가 5인 문자열에서 마지막 글자의 인덱스는?프그02-01
더 알아보기
심화문자열은 바꿀 수 없다
Python에서 말[0] = "코" 처럼 글자 하나만 바꾸려 하면 오류가 난다. 문자열은 한 번 만들면 바꿀 수 없는 값이기 때문이다. 바꾸려면 새 문자열을 만들어야 한다 — 말 = "코" + 말[1:]. 처음에는 불편해 보이지만, 값이 조용히 바뀌지 않는다는 보장이 있어 프로그램을 이해하기 쉬워진다. 반대로 C의 문자 배열은 word[0] = 'P'; 처럼 바로 바꿀 수 있다. 같은 “문자열”이라도 언어에 따라 성질이 다르다.
실무자주 쓰는 문자열 기능
이 차시에서는 자르기와 길이만 다뤘지만 실제로는 이런 것들을 더 쓴다. 찾기(어디에 있는가), 바꾸기(특정 글자를 다른 글자로), 나누기(쉼표를 기준으로 여러 조각으로), 공백 없애기(앞뒤의 빈칸 제거), 대소문자 바꾸기. 입력받은 값을 검사할 때 특히 공백 없애기를 자주 쓴다 — 사용자가 실수로 앞에 빈칸을 넣는 일이 흔하기 때문이다. 필요할 때 찾아 쓰면 되고, 무엇을 찾아봐야 하는지 아는 것이 지금 단계에서 더 중요하다.
심화글자를 숫자로 저장한다
컴퓨터는 글자도 숫자로 저장한다. 영문 A 는 65, a 는 97이다. 이 약속을 아스키(ASCII) 코드라 한다. C에서 word[0] 이 char 형인 것은 그래서다 — 문자는 작은 정수인 셈이다. 그래서 C에서 'a' - 'A' 를 계산하면 32가 나오고, 이것으로 대소문자를 바꾸는 계산을 할 수 있다. 한글처럼 세계의 모든 글자를 담으려면 아스키로는 모자라, 유니코드라는 더 큰 약속을 쓴다. UTF-8은 유니코드를 바이트로 적는 방법 중 하나이며, 한글 한 글자가 3바이트가 되는 이유가 여기 있다.
이어지는 학습
이 차시를 이해하려면 다음을 먼저 알아야 한다.
- 2차시의 자료형 구분 — 프로그래밍 프그02-01
교과서에서 찾기
| 교과서 | 해당 위치 | 쪽수 |
|---|---|---|
| 성림출판(Python) | 프로그래밍의 기초 › 01 변수와 자료형 | 58쪽 |
| 씨마스커뮤니케이션(Python) | 프로그래밍 기초 › 2 변수와 자료형 | 84쪽 |
| 삼양미디어(Python) | 프로그래밍의 기초 › 01 데이터 입출력 (프그02-02와 통합) | 42쪽 |
| 삼양미디어(C) | 프로그래밍의 기초 › 01 데이터 입출력 (프그02-02와 통합) | 42쪽 |
| 씨마스(C) | C 프로그래밍의 기초 › 1 변수와 자료형 | 62쪽 |
| 웅보출판사(C) | 프로그래밍의 기초 › Chapter 01 변수와 자료형 | 61쪽 |