C언어 문자열 완벽 정리: NULL 문자부터 문자열 함수, 입출력까지
이번 글에서는 C언어 문자열에 관한 핵심 개념들을 꼼꼼하게 정리합니다. NULL 문자
란 무엇인지, 문자열 초기화 방법, 입출력 함수 사용법, 그리고 문자열 처리에 유용한 다양한 함수들을 자세히 설명하며 예제 코드와 함께 쉽게 이해할 수 있도록 작성했습니다.
1. NULL 문자(종료 문자)란?
문자열의 끝을 나타내는 특별한 문자로, '\0'
(널 문자)라고 부릅니다. 문자열은 내부적으로 이 NULL 문자를 만날 때까지 계속 출력됩니다. 예를 들어:
char str[] = "abc";
printf("%s", str); // abc 출력, 내부적으로 "a", "b", "c", '\0'로 저장됨
만약 배열 선언 시 문자열 길이보다 배열 크기가 크면, 나머지 공간은 자동으로 '\0'
문자로 채워집니다.
주의! printf(str);
처럼 형식 지정자 없이 문자열 변수를 바로 출력하려 하면 에러가 발생할 수 있으니 항상 printf("% s", str);
형식을 사용하세요.
2. 문자열 저장 공간과 초기화 방법
문자열을 저장하는 공간은 크게 두 가지로 나눌 수 있습니다:
- 스택 메모리: 지역 변수로 선언된 문자열 배열
- 힙 메모리:
malloc
등으로 동적 할당한 공간
문자열 초기화 방법은 다양합니다.
char str [] = "HELLO";
// 문자열 상수로 초기화char str[] = {'H', 'E', 'L', 'L', 'O', '\0'};
// 문자 배열 직접 초기화char str [6]; strcpy(str, "HELLO");
// 문자열 복사char* str = (char*) malloc(6 * sizeof(char)); strcpy(str, "HELLO");
// 동적 할당 후 복사
3. 문자 입출력 함수
문자를 입출력할 때는 버퍼를 사용하기 때문에 Enter
키를 눌러야 입력이 처리됩니다.
#include <stdio.h>
int main(void) {
int ch; // getchar() 반환형은 int!
while ((ch = getchar()) != EOF) {
putchar(ch);
}
return 0;
}
int getchar(void)
: 한 문자 읽기 (버퍼 사용)void putchar(int c)
: 한 문자 출력 (버퍼 사용)EOF
: 파일 끝 표시, 보통 -1
버퍼를 사용하지 않는 함수들도 있는데, <conio.h>
에 포함된 다음과 같습니다:
_getch()
: 입력 문자 에코(화면 출력) 없음_getche()
: 입력 문자 에코 있음 (입력 문자 두 번 출력되는 현상 주의)_putch()
: 버퍼 사용 없이 문자 출력
4. 문자열 읽기와 출력 함수
gets_s(char s [], int length)
: 한 줄 전체 문자열 읽기 (보안 강화 버전)puts(char s []):
문자열 출력 (자동으로 줄 바꿈 포함)
참고: gets_s
는 환경에 따라 작동하지 않을 수 있고, 사용을 권장하지 않습니다. 대신 fgets
를 사용하는 것이 안전합니다.
5. <ctype.h>
- 문자 판별 및 변환 함수
이 함수들은 인자로 int
형을 받지만 char
형도 사용할 수 있습니다.
isalpha(c)
: 영문자 여부 검사isupper(c)
: 대문자 여부islower(c)
: 소문자 여부toupper(c)
: 소문자를 대문자로 변환tolower(c)
: 대문자를 소문자로 변환toascii(c)
: 문자를 ASCII 코드로 변환
6. <string.h>
- 문자열 처리 함수
strlen(s)
: 문자열 길이 반환 (NULL 문자 제외)strcpy(s1, s2)
: s2를 s1에 복사strcat(s1, s2)
: s2를 s1 끝에 이어 붙임strcmp(s1, s2)
: 문자열 사전 순 비교 (음수: s1 < s2, 0: 같음)strncpy(s1, s2, n)
: 최대 n 문자만 복사strchr(s, c)
: 문자열 s에서 문자 c 탐색strstr(s1, s2)
: s1에서 s2 문자열 찾기 (포인터 반환)strtok(s, seps)
: 토큰 분리 함수, 구분자 문자열 seps 기준으로 문자열 분리
예를 들어 토큰 분리:
char* token;
char seps[] = ",\t\n";
token = strtok(s, ",");
while(token != NULL) {
// 토큰 처리
token = strtok(NULL, ",");
}
7. 문자열과 숫자 변환 및 포맷 함수
sscanf(s, "% s % d", name, &number)
: 문자열 s에서 형식에 맞게 데이터 읽기sprintf(s, "정수 % d 더하기 % d는 % d다.", x, y, result)
: 형식화된 문자열을 s에 저장atoi(const char* str)
: 문자열을 정수로 변환atof(const char* str)
: 문자열을 실수(double)로 변환
8. 문자열 저장 방식과 주의사항
- 문자열은
char
배열에'\0'
이 포함된 형태로 저장됩니다. - 변경 가능한 문자열은 스택 또는 힙에 저장되며,
char* p = "HELLO"처럼
선언된 문자열은 텍스트 세그먼트에 저장되어 수정 불가합니다. char s []는
배열이므로 수정 가능하지만,char* s
에 문자열 리터럴을 직접 할당하면 수정하면 안 됩니다.char a [][]
(2차원 배열 형태)는 문자열 배열로 바로 초기화하기 어렵고, 대신char* a []
같은 포인터 배열로 관리합니다.gets_s
같은 함수는 사용을 권장하지 않으며, 버퍼 크기를 직접 지정할 수 있는fgets
를 활용하세요.
마무리
이번 포스팅을 통해 C언어에서 문자열을 다룰 때 꼭 알아야 하는 기본 개념부터 고급 함수 활용법까지 폭넓게 다뤘습니다. 문자열은 단순한 문자 배열이 아니라, 끝을 알리는 NULL 문자('\0')
가 필수이며, 입출력 함수와 다양한 문자열 처리 함수들을 올바르게 사용하는 것이 중요합니다.
특히 포인터와 함께 쓰이는 경우가 많으므로, 포인터의 개념을 확실히 익히고, 메모리 구조를 이해하는 것이 문자열 처리를 정확하게 하는 데 큰 도움이 됩니다.
궁금한 점이나 추가로 알고 싶은 부분이 있으면 언제든 댓글로 남겨주세요!
'공부 > C언어' 카테고리의 다른 글
[C언어] C언어 파일 입출력 완벽 정리 - C언어 파일 스트림과 파일 처리 기초 (2) | 2025.06.14 |
---|---|
[C언어] C언어 구조체, 공용체, 열거형 - C언어 핵심 개념 정리 (0) | 2025.06.14 |
[C언어] C언어 포인터 완전 정복: 함수 포인터와 다양한 포인터 활용법 (0) | 2025.06.14 |
[C언어] C언어 포인터 완벽 정리와 핵심 개념 (0) | 2025.06.14 |
[C언어] C언어 함수(Function)의 이해와 활용 – 체계적인 프로그래밍의 시작 (1) | 2025.06.14 |