문자열(string)은 간단히 말하면 문자의 집합을 뜻한다.
C언어는 문자 배열이나 포인터를 사용하여 문자열을 다룹니다.
문자열의 마지막에는 NULL 문자('\0')가 포함되어, 문자열의 끝을 나타낸다.
NULL 문자는 문자열의 길이를 결정하는 데 중요한 역할을 한다.
char data1 = 'H';
char data2 = 'e';
char data3 = 'l';
char data4 = 'l';
char data5 = 'o';
문자 배열을 사용하여 문자열을 선언하고 초기화하는 것은 문자열을 저장할 공간을 메모리에 직접 할당하는 방식이다.
char str1[14] = "Hello, World!"; // 명시적 크기 선언과 초기화
char str2[] = "Hello, World!"; // 컴파일러가 크기를 계산하여 할당
위의 예시에서 str1
은 크기를 명시적으로 14로 지정했고(문자열 길이 + 널 문자), str2
는 컴파일러가 문자열 리터럴의 길이를 계산하여 자동으로 크기를 할당한다. 두 경우 모두 배열의 끝에는 자동으로 널 문자('\0')가 추가되어 문자열의 끝을 나타낸다.
문자 포인터를 사용하여 문자열을 선언하고 초기화하는 방식은 문자열 리터럴의 주소를 포인터 변수에 저장하는 것이다. 이 방법으로 초기화된 문자열은 읽기 전용 메모리 영역에 저장된다.
char *str = "Hello, World!";
이 경우, str
은 문자열 "Hello, World!"의 첫 번째 문자 'H'를 가리키는 포인터다. 문자열 리터럴은 프로그램의 읽기 전용 메모리 세그먼트에 저장되며, c을 통해 이 문자열에 접근할 수 있다.
C언어에서 문자를 저장하는 데 가장 적합한 자료형은 char
형이다.
그래서 문자령릉 저장하려면 char
형 변수를 그룹으로 묶어서 관리하는 char
배열을 사용해야 한다.
char data[6] = {'h', 'a', 'p', 'p', 'y', 0};
/* 문자 개수는 5개고 끝에 0을 덧붙여야 하므로 배열의 크기는 6 */
다음과 같은 문자열 선언이 있을 때:
char str[] = "Hello";
str은 문자 배열을 가리키는 포인터다. 이 경우, str은 'H’를 가리키며, 이는 문자열의 첫 번째 문자이다.
문자열을 가리키는 포인터를 사용하면 문자열의 각 문자에 접근하거나 문자열을 수정하는 등의 작업을 수행할 수 있다. 예를 들어, 다음과 같이 문자열의 특정 문자에 접근할 수 있습니다:
char c = str[1]; /* 'e' */
또한, 문자열을 가리키는 포인터를 사용하면 문자열을 함수에 전달하거나 함수에서 반환하는 등의 작업을 수행할 수 있다.
C언어에서 문자열을 다루기 위해 표준 라이브러리에서 제공하는 여러 함수들이 있다.
이 함수들은 <string.h> 헤더 파일에 선언되어 있으며, 문자열 복사, 비교, 연결, 검색 등 다양한 작업을 수행할 수 있게 해준다.
String Copy: strncpy()
-> 문자열 복사
String Concate: strncat()
-> 문자열 연결
/* 두 개의 문자열 합치기 */
#include <stdio.h>
#include <string.h>
void main(){
char data[10] = {'a, 'b', 'c', 0,};
char result[16];
strcpy(result, data);
strcat(result, "def");
printf("%s + \"def\" = %s\n", data, result);
}
String Compare: strncmp()
-> 문자열 비교
First Character Occurrence: strchr()
-> 문자열 첫 발생 위치 찾기
Last Character Occurrence: strrchr()
-> 문자열 마지막 발생 위치 찾기
String Search: strstr()
-> 부분 문자열 첫 검색
String Token Break: strtok()
-> 구분기호 기준으로 문자열 토근 나누기
Lowercase String: strlwr()
-> 소문자 변환
Uppercase String: strupr()
-> 대문자 변환
Duplicate String: strdup()
-> 문자열 복제
strlen(str): 문자열 str의 길이를 반환
#include <stdio.h>
#include <string.h>
void main(){
int data_length; /* 문자열 길이를 저장할 변수 */
char data[10] = {'h', 'a', 'p', 'p', 'y', 0};
data_length = strlen(data);
printf("data length = %d\n", data_length);
}
strcpy(char *dest, const char *src)
: src
문자열을 dest
로 복사합니다. dest
가 충분히 크지 않아 오버플로우가 발생할 수 있으니 주의해야 합니다.strncpy(char *dest, const char *src, size_t n)
: src
문자열의 처음 n
개 문자를 dest
로 복사합니다. 오버플로우를 방지할 수 있지만, n
개 문자를 복사한 후 추가적으로 널 문자를 붙여주지 않는다는 점을 주의해야 합니다.strcmp(const char *str1, const char *str2)
: str1
과 str2
문자열을 비교합니다. 두 문자열이 같으면 0을, str1
이 str2
보다 크면 양수를, 작으면 음수를 반환합니다.strncmp(const char *str1, const char *str2, size_t n)
: str1
과 str2
문자열의 처음 n
개 문자를 비교합니다. 비교 방식은 strcmp
와 동일합니다.strcat(char *dest, const char *src)
: src
문자열을 dest
문자열의 끝에 연결합니다. dest
의 크기가 충분히 큰지 확인해야 합니다.strncat(char *dest, const char *src, size_t n)
: src
문자열의 처음 n
개 문자를 dest
문자열의 끝에 연결합니다. dest
의 크기가 충분히 큰지 확인해야 하며, 연결 후 널 문자로 끝나는지 확인해야 합니다.strlen(const char *str)
: str
문자열의 길이를 반환합니다. 여기서 길이란 널 문자를 제외한 문자의 개수입니다.strchr(const char *str, int c)
: str
문자열에서 처음으로 c
가 나타나는 위치의 포인터를 반환합니다. 만약 c
가 문자열에 없으면 NULL
을 반환합니다.strrchr(const char *str, int c)
: str
문자열에서 마지막으로 c
가 나타나는 위치의 포인터를 반환합니다.strstr(const char *haystack, const char *needle)
: haystack
문자열 내에서 needle
문자열이 시작하는 첫 번째 위치의 포인터를 반환합니다. 만약 needle
이 haystack
에 없으면 NULL
을 반환합니다.strtok(char *str, const char *delim)
: 문자열을 delim
에 포함된 하나 이상의 문자를 기준으로 토큰으로 분리합니다. 첫 번째 호출에서는 문자열의 포인터를, 이후 호출에서는 NULL
을 str
인자로 제공해야 합니다.
// 다음과 같은 코드를 이해해봅시다. #include <stdio.h> void reverse(char* str) { int len = 0; while(str[len] != '\0') { len++; } for(int i=0; i<len/2; i++) { char temp = str[i]; str[i] = str[len-i-1]; str[len-i-1] = temp; } } int main() { char str[] = "Hello, World!"; reverse(str); printf("%s\\n", str); return 0; }
!dlroW ,olleH\n
// 아래의 코드의 실행 결과를 예상하여 봅시다 #include <stdio.h> #include <string.h> int find_char(char* str, char c) { for(int i=0; str[i] != '\0'; i++) { if(str[i] == c) { return i; } } return -1; } int main() { char str[] = "Hello, World!"; char c = 'o'; int pos = find_char(str, c); if(pos != -1) { printf("The character '%c' found at position %d\\n", c, pos); } else { printf("The character '%c' not found\\n", c); } return 0; }
The character 'o' found at position 4\n
- strcat(), strcpy(), strcmp() 등등 기본 문자열 함수를 구현해보기 (string 헤더 include 금지!!)
myStrcat()
- 두 단어를 입력받는다.
- 두 단어를 합친 결과를 출력한다.
ex)
Input first word : Knock
Input second word : On!
KnockOn!
#include <stdio.h>
void myStrcat(char *dest, const char *src) {
/* dest의 끝을 찾기 */
while (*dest) {
dest++;
}
/* src의 내용을 dest의 끝부터 복사 */
while (*src) {
*dest = *src;
dest++;
src++;
}
*dest = '\0';
}
int main() {
char firstWord[100];
char secondWord[100];
printf("Input first word: ");
scanf("%s", firstWord);
printf("Input second word: ");
scanf("%s", secondWord);
myStrcat(firstWord, secondWord);
printf("%s\n", firstWord);
return 0;
}
myStrcpy()
- 단어를 입력받는다.
- 다른 배열에 문자열을 복사한 후 복사본을 출력한다.
ex)
Input word : KnockOn!
KnockOn!
#include <stdio.h>
void myStrcpy(char *dest, const char *src) {
/* src에서 dest로 문자를 하나씩 복사 */
while (*src) {
*dest = *src;
dest++;
src++;
}
*dest = '\0';
}
int main() {
char originalWord[100];
char copiedWord[100];
printf("Input word: ");
scanf("%s", originalWord);
myStrcpy(copiedWord, originalWord);
printf("%s\n", copiedWord);
return 0;
}
myStrcmp()
- 두 단어를 입력받는다.
- 두 단어의 비교 결과를 출력한다.
ex)
Input first word : Knock
Input second word : On!
Nope..
#include <stdio.h>
int myStrcmp(const char *str1, const char *str2) {
/* str1과 str2를 한 글자씩 비교 */
while (*str1 && (*str1 == *str2)) {
str1++;
str2++;
}
/* 두 문자열의 차이를 반환 */
return *(const unsigned char*)str1 - *(const unsigned char*)str2;
}
int main() {
char firstWord[100];
char secondWord[100];
printf("Input first word: ");
scanf("%s", firstWord);
printf("Input second word: ");
scanf("%s", secondWord);
int result = myStrcmp(firstWord, secondWord);
if (result == 0) {
printf("Same!\n");
} else {
printf("Nope..\n");
}
return 0;
}
- 추가적인 문자열 함수 만들어 보기
void myNoSpace(char* str) {}
- 문장을 입력받는다.
- 문자열 사이 공백을 제거한 후 출력한다.
ex)
Input sentence : Hello Knock On!
HelloKnockOn!
#include <stdio.h>
void myNoSpace(char* str) {
char* dest = str; /* dest는 공백이 제거될 위치를 가리킴 */
while (*str != '\0') {
if (*str != ' ') { /* 현재 문자가 공백이 아니면, dest 위치에 복사하고 dest를 한 칸 이동 */
*dest = *str;
dest++;
}
str++; /* 원본 문자열에서 다음 문자로 이동 */
}
*dest = '\0'; /* 새로운 문자열의 끝에 널 문자를 추가 */
}
int main() {
char sentence[100];
printf("Input sentence: ");
fgets(sentence, sizeof(sentence), stdin); /* fgets를 사용하여 공백을 포함한 문장을 입력 받음 */
myNoSpace(sentence);
printf("%s\n", sentence);
return 0;
}