본문 바로가기
XR개발/C언어

C언어 문자와 문자열

by 오머리쿠_OmaryKoo 2025. 3. 2.

프로그래밍에서 문자는 단순한 기호 이상의 의미를 가진다. 특히 C 언어에서는 문자를 다룰 때 개별 문자와 문자열을 명확히 구분해야 한다. 이번 글에서는 C에서 문자와 문자열을 처리하는 방법을 알아보고, 포인터를 활용한 문자열 조작 기법까지 살펴본다.


1. 문자(Character)와 문자열(String)의 차이

C 언어에서는 개별 문자를 char형으로 다루고, 여러 개의 문자가 연속된 형태를 문자열이라고 한다.

char c = 'A';  // 하나의 문자
char str[] = "Hello";  // 문자열

위 예제에서 c는 단일 문자 'A'를 저장하는 변수이고, str은 "Hello"라는 문자열을 저장하는 문자 배열이다. 중요한 점은 문자열의 끝에는 항상 NULL 문자(``) 가 포함되어 있어야 한다는 것이다.


A. 문자열 저장 방식과 메모리 배치

문자는 메모리에 개별적으로 저장되지만, 문자열은 문자들이 연속된 형태로 저장된다.

char str1[] = "Hello";
char *str2 = "Hello";
  • str1은 문자 배열로 선언되었기 때문에 배열의 각 요소를 개별적으로 변경할 수 있다.
  • str2는 문자열 상수를 가리키는 포인터이며, 문자열 상수는 읽기 전용 영역(텍스트 세그먼트) 에 저장된다.
  • 따라서 str1[0] = 'W';는 가능하지만, str2[0] = 'W';는 런타임 오류를 발생시킨다.

메모리 배치를 그림으로 나타내면 다음과 같다.

str1: | H | e | l | l | o | \0 |  (데이터 세그먼트, 값 변경 가능)
str2:  주소 → "Hello"  (텍스트 세그먼트, 읽기 전용)

문자열을 포인터로 다룰 때 이러한 차이를 반드시 이해해야 한다.


B. NULL 문자와 문자열 종료

C 언어에서 문자열의 끝을 나타내기 위해 NULL 문자(``) 가 필요하다. 이는 문자열을 올바르게 처리하기 위한 중요한 개념이다.

char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};
  • str의 마지막에는 반드시 \0이 포함되어야 문자열로 인식된다.
  • printf("%s", str);을 사용하면 NULL 문자를 만날 때까지 출력된다.
  • 만약 \0이 없다면 쓰레기 값이 포함될 수 있다.

C. 문자열 조작 함수

C에서는 문자열을 다룰 수 있는 다양한 표준 라이브러리 함수를 제공한다.

 

1) 문자열 복사 (strcpy)

char str1[10] = "Hello";
char str2[10];
strcpy(str2, str1);  // str2에 str1의 내용 복사

 

2) 문자열 연결 (strcat)

char str1[20] = "Hello, ";
char str2[] = "World!";
strcat(str1, str2);  // str1에 str2의 내용을 이어 붙임

 

3) 문자열 길이 (strlen)

char str[] = "Hello";
printf("문자열 길이: %d", strlen(str));

 

4) 문자열 비교 (strcmp)

char str1[] = "abc";
char str2[] = "def";
if (strcmp(str1, str2) == 0) {
    printf("문자열이 같습니다.");
} else {
    printf("문자열이 다릅니다.");
}

D. 포인터와 문자열

문자열을 처리할 때 포인터를 사용하면 보다 효율적인 코드를 작성할 수 있다.

char *str = "Hello";
printf("%s", str);

포인터를 활용하면 문자열을 동적으로 할당할 수도 있다.

char *str = (char*)malloc(20);
strcpy(str, "Dynamic String");
printf("%s", str);
free(str);

이처럼 문자열을 다룰 때는 배열과 포인터의 차이를 이해하고, 적절한 방식으로 데이터를 관리하는 것이 중요하다.


2. C 언어 문자 및 문자열 입출력 라이브러리 정리

A. 문자 입출력 라이브러리

1) 문자 입력 함수

C 언어에서는 기본적으로 scanf()와 같은 함수를 이용하여 문자를 입력받을 수 있지만, 더 간단하고 직관적인 입력 함수들이 제공된다.

함수 설명
int getchar(void) 한 개의 문자를 입력받아 반환한다 (버퍼 사용).
void putchar(int c) 한 개의 문자를 출력한다.
int _getch(void) 입력된 문자를 버퍼 없이 즉시 반환한다.
void _putch(int c) 버퍼 없이 한 개의 문자를 출력한다.

 

2) getchar()와 putchar() 사용 예제

#include <stdio.h>

int main() {
    char ch;
    printf("문자 입력: ");
    ch = getchar();
    printf("입력한 문자: ");
    putchar(ch);
    return 0;
}

getchar()는 엔터를 입력해야 동작하지만, _getch()는 입력 즉시 동작하여 키보드 입력을 실시간으로 처리할 때 유용하다.


B. 문자열 입출력 라이브러리

1) 문자열 입력 및 출력 함수

함수 설명
int scanf("%s", str); 공백을 기준으로 한 단어를 입력받아 저장.
int printf("%s", str); 문자열을 출력.
char *gets_s(char *str, int size); 한 줄 전체를 입력받아 저장.
int puts(const char *str); 문자열을 출력하고 개행 문자 추가.

 

2) scanf()와 gets_s() 비교

#include <stdio.h>

int main() {
    char name[100];
    printf("이름을 입력하세요: ");
    gets_s(name, sizeof(name));
    printf("안녕하세요, %s님!\n", name);
    return 0;
}

gets_s()는 공백을 포함한 전체 입력을 받을 수 있지만, scanf("%s", str)는 공백을 기준으로 잘린다.


C. 문자 처리 라이브러리

1) 문자 검사 함수

C 언어에서는 특정 문자들이 대문자인지, 숫자인지 등을 검사하는 함수를 제공한다.

함수 설명
isalpha(c) 영문자 여부 (A-Z, a-z) 확인
isdigit(c) 숫자인지 확인 (0-9)
isspace(c) 공백 문자 여부 확인
isupper(c) 대문자 여부 확인
islower(c) 소문자 여부 확인

 

2) 문자 변환 함수

함수 설명
toupper(c) 소문자를 대문자로 변환
tolower(c) 대문자를 소문자로 변환

 

3) 문자 검사 및 변환 예제

#include <stdio.h>
#include <ctype.h>

int main() {
    char ch;
    printf("문자 입력: ");
    ch = getchar();
    if (islower(ch)) {
        ch = toupper(ch);
    }
    printf("변환된 문자: %c\n", ch);
    return 0;
}

이 코드는 사용자가 소문자를 입력하면 대문자로 변환하여 출력하는 프로그램이다.


D. 문자열 처리 응용

1) 단어 개수 세기 프로그램

#include <stdio.h>
#include <ctype.h>

int count_words(char *s) {
    int i, wc = 0, waiting = 1;
    for (i = 0; s[i] != '\0'; i++) {
        if (isalpha(s[i]) && waiting) {
            wc++;
            waiting = 0;
        } else if (!isalpha(s[i])) {
            waiting = 1;
        }
    }
    return wc;
}

int main() {
    char str[] = "Hello world, this is C programming!";
    printf("단어 개수: %d\n", count_words(str));
    return 0;
}

이 프로그램은 공백이나 특수 문자를 기준으로 문자열 속 단어 개수를 세는 기능을 한다.


3. C 언어 문자열 처리 라이브러리 함수 정리

A. 문자열 처리의 중요성

C 언어에서 문자열은 단순한 문자들의 집합이 아니라, 프로그램의 데이터 처리와 입력/출력에서 중요한 역할을 한다. 하지만 C 언어에서는 기본적으로 문자열을 다루는 전용 자료형이 없으며, 대신 char 배열과 포인터를 이용해야 한다. 이를 효율적으로 처리하기 위해 표준 라이브러리에서 문자열을 다루는 다양한 함수들을 제공한다.


B. 문자열 관련 라이브러리 string.h

C 언어에서 문자열을 다루려면 반드시 string.h 헤더 파일을 포함해야 합니다. string.h에는 문자열의 길이 계산, 복사, 연결, 비교, 검색, 토큰 분리 등 여러 기능을 수행하는 함수들이 포함되어 있습니다.

#include <string.h>

C. 문자열 길이 계산

strlen() 함수

문자열의 길이를 구할 때 사용됩니다. NULL(\0) 문자를 제외한 문자 개수를 반환합니다.

int length = strlen("Hello"); // 결과: 5

D. 문자열 복사 및 연결

strcpy() 함수

문자열을 다른 문자열로 복사할 때 사용됩니다. 복사할 대상(dst)이 충분한 크기를 가져야 합니다.

char dst[10];
strcpy(dst, "Hello");

 

strncpy() 함수

특정 개수의 문자만 복사하고 싶다면 strncpy()를 사용합니다.

char dst[10];
strncpy(dst, "Hello", 3); // dst에 "Hel"만 복사됨

 

strcat() 함수

두 개의 문자열을 하나로 연결할 때 사용됩니다. 기존 문자열의 끝에 새로운 문자열을 추가합니다.

char dst[20] = "Hello";
strcat(dst, " World");
// 결과: "Hello World"

 

strncat() 함수

특정 개수의 문자만 추가할 경우 사용됩니다.

char dst[20] = "Hello";
strncat(dst, " World", 3); // 결과: "Hello Wor"

E. 문자열 비교

strcmp() 함수

두 문자열을 비교하여 같은 경우 0, 첫 번째 문자열이 크면 양수, 두 번째 문자열이 크면 음수를 반환합니다.

int result = strcmp("apple", "banana"); // 결과: 음수

 

strncmp() 함수

문자열의 앞부분 일부만 비교할 경우 사용됩니다.

int result = strncmp("apple", "apricot", 3); // 결과: 0 (앞 3문자가 같음)

F. 문자열 검색

strchr() 함수

특정 문자가 문자열 내에서 처음 등장하는 위치를 찾습니다.

char *p = strchr("Hello", 'e'); // 결과: 'e'의 주소 반환

 

strstr() 함수

부분 문자열(서브스트링)을 검색하여 처음 등장하는 위치를 반환합니다.

char *p = strstr("Hello World", "World"); // "World"의 시작 주소 반환

G. 문자열 토큰 분리

strtok() 함수

문자열을 특정 구분자(delimiter)를 기준으로 나누는 함수입니다.

char str[] = "Hello,World";
char *token = strtok(str, ",");
while (token != NULL) {
    printf("%s\n", token);
    token = strtok(NULL, ",");
}
// 결과:
// Hello
// World

4.C 언어의 문자열 및 문자 처리 라이브러리 활용

A. 문자 입출력 라이브러리

getchar()와 putchar()

C 언어에서 한 문자씩 입력받거나 출력할 때 getchar()와 putchar() 함수를 사용할 수 있다.

#include <stdio.h>
int main(void) {
    int ch;
    printf("문자를 입력하세요: ");
    ch = getchar(); // 한 문자 입력
    printf("입력한 문자: ");
    putchar(ch); // 입력한 문자 출력
    return 0;
}

 

getch()와 getche()

getch()와 getche() 함수는 <conio.h> 헤더 파일을 포함해야 하며, 버퍼를 사용하지 않아 입력한 문자가 바로 전달된다.

#include <conio.h>
#include <stdio.h>
int main(void) {
    char ch;
    printf("문자를 입력하세요: ");
    ch = getch(); // 입력한 문자가 화면에 표시되지 않음
    printf("\n입력한 문자: ");
    putchar(ch);
    return 0;
}

B. 문자열 입출력 라이브러리

scanf()와 printf()를 이용한 문자열 입출력

문자열을 입력받고 출력할 때 scanf()와 printf()를 사용할 수 있다.

#include <stdio.h>
int main(void) {
    char name[50];
    printf("이름을 입력하세요: ");
    scanf("%s", name);
    printf("안녕하세요, %s님!\n", name);
    return 0;
}

하지만 scanf("%s", name);은 공백을 포함한 문자열을 입력받을 수 없기 때문에 gets_s()를 사용하는 것이 좋다.

#include <stdio.h>
int main(void) {
    char sentence[100];
    printf("한 줄의 문장을 입력하세요: ");
    gets_s(sentence, sizeof(sentence));
    printf("입력된 문장: %s\n", sentence);
    return 0;
}

C. 문자열 처리 라이브러리

문자열 길이 계산: strlen()

strlen() 함수는 문자열의 길이를 계산할 때 사용된다.

#include <stdio.h>
#include <string.h>
int main(void) {
    char str[] = "Hello, World!";
    printf("문자열의 길이: %lu\n", strlen(str));
    return 0;
}

 

문자열 복사와 연결: strcpy()와 strcat()

#include <stdio.h>
#include <string.h>
int main(void) {
    char src[] = "C programming";
    char dest[50];
    strcpy(dest, src);
    strcat(dest, " is fun!");
    printf("%s\n", dest);
    return 0;
}

 

문자열 비교: strcmp()

문자열을 비교할 때는 strcmp()를 사용하며, 사전순 정렬을 기준으로 값이 반환된다.

#include <stdio.h>
#include <string.h>
int main(void) {
    char str1[] = "apple";
    char str2[] = "banana";
    if (strcmp(str1, str2) < 0) {
        printf("%s이 %s보다 앞에 있습니다.\n", str1, str2);
    } else {
        printf("%s이 %s보다 뒤에 있습니다.\n", str1, str2);
    }
    return 0;
}

D. 문자열을 숫자로 변환

문자열을 정수나 실수로 변환할 때는 atoi()와 atof()를 사용한다.

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    char numStr[] = "123";
    int num = atoi(numStr);
    printf("정수 변환: %d\n", num);
    return 0;
}

E. 2차원 문자 배열과 문자열 저장

2차원 문자 배열을 이용한 문자열 저장

#include <stdio.h>
int main(void) {
    char words[3][10] = {"Hello", "World", "C"};
    for (int i = 0; i < 3; i++) {
        printf("%s\n", words[i]);
    }
    return 0;
}

 

문자열 포인터 배열 사용

#include <stdio.h>
int main(void) {
    char *words[] = {"Hello", "World", "C"};
    for (int i = 0; i < 3; i++) {
        printf("%s\n", words[i]);
    }
    return 0;
}

F. 간단한 사전 프로그램 (문자열 검색)

사전처럼 단어를 저장하고 검색하는 프로그램을 만들 수 있다.

#include <stdio.h>
#include <string.h>
#define WORDS 3
int main(void) {
    char dic[WORDS][2][30] = {
        {"apple", "사과"},
        {"banana", "바나나"},
        {"cherry", "체리"}
    };
    char word[30];
    printf("단어를 입력하세요: ");
    scanf("%s", word);
    for (int i = 0; i < WORDS; i++) {
        if (strcmp(dic[i][0], word) == 0) {
            printf("%s: %s\n", word, dic[i][1]);
            return 0;
        }
    }
    printf("사전에 단어가 없습니다.\n");
    return 0;
}

이처럼 C 언어에서는 다양한 문자열 및 문자 입출력 관련 라이브러리를 활용하여 효율적인 문자열 처리 프로그램을 만들 수 있다.

728x90

'XR개발 > C언어' 카테고리의 다른 글

C 오답노트02_산술연산자 & 선택제어문(조건문)  (0) 2025.03.19
C오답노트01_출력과 입력  (0) 2025.03.19
C언어 포인터  (0) 2025.03.01
C언어 배열  (2) 2025.02.28
10_Q&A 함수원형에 대한 물음.zip  (0) 2025.02.16