처음에는 C언어에는 문자배열만 다뤘다고 합니다. 문자배열은 말 그대로 문자로 이루어진 배열이기 때문에 문자배열의 선두번지 주소값, 배열의 요소의 갯수를 둘 다 전달해야하는 불편함을 가지고 있었습니다. 그에 따른 오류확률도 올라갔습니다.
그러한 불편함 때문에 문자배열뒤에 널종료문자(\0)를 넣고, 문자배열뒤에 널종료문자가 있는 것을 문자열이라고 정의를 했습니다. 널종료문자의 역할은 문자열의 끝을 나타내줍니다. 프로그램에서 문자열을 인식할 때 널종료문자를 만나면 문자열의 끝이라고 인식합니다. 따라서 배열의 요소으 갯수 즉, 문자열의 길이를 일일히 전달해야 하는 불편함이 없어졌습니다.
앞에서 말했듯이 문자배열은 널종료문자가 없어서 문자배열 길이를 항상 달고다녀야 하지만, 문자열은 널종료문자가 있어서 문자열 자체만으로도 여러가지를 해결할 수 있습니다.

예시
#include <stdio.h>
//문자배열 출력함수
void PrintCharArray(char* str, int size) {
for (int i = 0; i < size; i++) {
putchar(str[i]); //putchar는 한 문자 출력함수
}
}
//문자열 출력함수
void PrintString(char* pStr) {
while (*pStr) {
putchar(*pStr);
pStr++;
}
}
int main() {
char str[] = { 'M', 'O', 'N', 'S', 'T', 'E', 'R' };//문자배열
char str2[] = "Monster";//문자열
char str3[] = { 'M', 'O', 'N', 'S', 'T', 'E', 'R', '\0' };//문자열
printf("str size = %d\n", sizeof(str));
printf("str size = %d\n", sizeof(str2));
printf("str size = %d\n", sizeof(str3));
printf("\n문자배열 출력함수\n");
printf("str문자배열\n");
PrintCharArray(str, sizeof(str));
printf("\n");
printf("str2문자열\n");
PrintCharArray(str2, sizeof(str2));
printf("\n");
printf("str3문자열\n");
PrintCharArray(str3, sizeof(str3));
printf("\n");
printf("\n문자열 출력함수\n");
printf("str문자배열=n");
PrintString(str);
printf("\n");
printf("str2문자열\n");
PrintString(str2);
printf("\n");
printf("str3문자열\n");
PrintString(str3);
return 0;
}
결과
str size = 7
str size = 8
str size = 8
문자배열 출력함수
str문자배열
MONSTER
str2문자열
Monster
str3문자열
MONSTER
문자열 출력함수
str문자배열
MONSTER儆儆儆儆儆儆儆儆儆儆儆儆儆儆?onster
str2문자열
Monster
str3문자열
MONSTER
참고 C라는 언어 자체가 오래된 언어이기 때문에, 문자열 함수 또한 오래되었습니다. 따라서 함수자체가 불안정한 함수가 많습니다. 그래서 오류 메시지를 강제로 끄는 #define _CRT_SECURE_NO_WARNINGS 라는 문구가 무조건 들어가야합니다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Monster";
printf("strlen\n");
int count = strlen(str);
printf("str : %s의 문자의 갯수는 %d\n", str, count);
return 0;
}
strlen
str : Monster의 문자의 갯수는 7
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Monster";
char str2[] = " is World!";
char buff[30];
printf("strcpy\n");
strcpy(buff, str);
printf("str: %s문자열을 buff: %s로 복사함\n", str, buff);
return 0;
}
strcpy
str: Monster문자열을 buff: Monster로 복사함
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Monster";
char str2[] = " is World!";
char buff[30];
printf("strcmp\n");
int ret = strcmp(str, buff);
if (ret == 0) {
printf("str: %s와 buff: %s 두 문자열이 같다.\n", str, buff);
}
else {
printf("str: %s와 buff: %s 두 문자열이 다르다.\n", str, buff);
}
ret = strcmp(str, str2);
if (ret == 0) {
printf("str: %s와 str2: %s 두 문자열이 같다.\n", str, str2);
}
else {
printf("str: %s와 str2: %s 두 문자열이 다르다.\n", str, str2);
}
return 0;
}
strcmp
str: Monster와 buff: Monster 두 문자열이 같다.
str: Monster와 str2: is World! 두 문자열이 다르다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
char str[] = " is World!";
char buff[30] = "Monster";
printf("strcat\n");
printf("buff: %s와 str: %s 두 문자열을 병합합니다.\n", buff, str);
strcat(buff, str);
printf("buff: %s에 두 문자열이 병합됨\n", buff);
return 0;
}
strcat
buff: Monster와 str: is World! 두 문자열을 병합합니다.
buff: Monster is World!에 두 문자열이 병합됨
toupper는 소문자를 대문자로 변경하고, tolower는 대문자를 소문자로 변경합니다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main() {
printf("toupper, tolower\n");
int ch = toupper('a');
printf("대문자로 변경: %c\n", ch);
ch = tolower('A');
printf("소문자로 변경: %c\n", ch);
return 0;
}
toupper, tolower
대문자로 변경: A
소문자로 변경: a
위의 문자열 함수들을 이용하여 간단한 구조체 배열 문제를 풀어보겠습니다.
typedef struct tagStudent {
char name[30];
int grade;
int classNum;
}Student;
Student stArray[] = {//구조체 배열
{"원숭이", 1, 3},
{"사자", 2, 11},
{"호랑이", 2, 8},
{"코끼리", 3, 7},
{"침팬지", 3, 5},
{"팬더", 1, 12}
};
이름을 입력 받고 위의 배열에서 입력받은 이름에 해당하는 데이타를 찾고 해당이름의 학생의 학년과 반을 출력하는 프로그램을 만드세요.
코드
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
typedef struct tagStudent {
char name[30];
int grade;
int classNum;
}Student;
int main() {
Student stArray[] = {//구조체 배열
{"원숭이", 1, 3},
{"사자", 2, 11},
{"호랑이", 2, 8},
{"코끼리", 3, 7},
{"침팬지", 3, 5},
{"팬더", 1, 12}
};
char inputName[30];
int length = sizeof(stArray) / sizeof(stArray[0]);
while (1) {
printf("찾는 이름을 입력하세요(exit: exit):");
scanf_s("%s", inputName, sizeof(inputName));
if (strcmp(inputName, "exit") == 0) {
printf("검색작업을 종료합니다.");
break;
}
for (int i = 0; i < length; i++) {
if (strcmp(inputName, stArray[i].name) == 0) {
printf("이름: %s\n학년: %d\n학번: %d\n", stArray[i].name, stArray[i].grade, stArray[i].classNum);
break;
}
else if (i == length - 1) {
printf("해당 이름이 존재하지 않습니다.\n");
}
}
}
return 0;
}
결과
찾는 이름을 입력하세요(exit: exit):원숭이
이름: 원숭이
학년: 1
학번: 3
찾는 이름을 입력하세요(exit: exit):사자
이름: 사자
학년: 2
학번: 11
찾는 이름을 입력하세요(exit: exit):기린
해당 이름이 존재하지 않습니다.
찾는 이름을 입력하세요(exit: exit):exit
검색작업을 종료합니다.