제 19강) 문자열 |
17강과 18강에서 우리는 포인터와 배열을 배웠습니다.
이제 우리는 문자열을 배울 차례입니다.
1) 문자열 |
문자열은 "문자(기호)를 모아놓은 것"을 뜻합니다.
C언어에서 문자열을 표현하는 방법은 2가지가 존재합니다.
char str[] = "Back In Time"; // char 배열을 이용한 문자열 표현
char* str = "Back In Time"; // char 포인터를 이용한 문자열 표현
2) char 배열을 사용한 문자열 |
일반적으로 문자열을 저장할 때 char 배열을 이용하여 문자열을 저장합니다.
#include <stdio.h>
int main()
{
char str[30] = {0,}; // 문자열의 최대 길이는 30
printf("문자열 입력: ");
scanf("%[^\n]s", str);
printf("입력한 문자열: %s \n", str);
return 0;
}
이때 배열의 크기만큼 문자열을 저장할 수 있습니다.
그럼 이렇게 입력된 문자열은 어떻게 구성되어있는지 알아봅시다.
이렇게 배열은 저장됩니다.
(위의 배열은 처음에 0으로 초기화를 했기 때문에 입력받지 않은 문자열의 구역에는 0이 저장됩니다.)
이때 문자열의 끝에는 문자열의 끝을 알려주는 "\0"가 들어가게 됩니다.
그렇기 때문에 배열의 길이는 "자신이 넣을 문자열의 길이 + 1"만큼 설정해야합니다.
여기서 주의해야할 점은
알파벳과는 달리 한글의 경우에는 2바이트를 사용합니다.
그렇기 때문에
#include <stdio.h>
int main()
{
char str1[30] = { 0, }; // 문자열의 최대 길이는 30
printf("문자열 입력: ");
scanf("%[^\n]s", str1);
printf("str1[0]: %c, str1[1]: %c, str1[2]: %c \n", str1[0], str1[1], str1[2]);
while (getchar() != '\n'); // 다음 입력문이 씹히는 것을
char str2[30] = { 0, }; // 문자열의 최대 길이는 30
printf("문자열 입력: ");
scanf("%[^\n]s", str2);
printf("str2[0]: %c, str2[1]: %c, str2[2]: %c \n", str2[0], str2[1], str2[2]);
return 0;
}
위와 같은 소스에서
한글 입력했을 때 배열에 직접 접근을 하면 문자가 깨져보입니다.
부록) 문자열을 입력받을 때는 &을 쓰지 않는다. |
바로 위의 예제를 보더라도
scanf("%[^\n]s", str1);
문자열은 scanf에서 입력될 배열에 &을 넣지 않습니다.
18강에서 배열과 포인터를 같이 설명할 때 다음과 같은 말을 했던것을 기억하시나요?
#include <stdio.h>
int main()
{
int arr[4] = {1, 2, 3, 4};
int* ptr = arr; // 포인터를 배열의 첫번째 인덱스에 연결(arr[0])
return 0;
}
포인터를 배열의 이름에 연결시키면 "배열의 첫요소"에 연결된다는 것을 말이죠.
문자열을 입력할때도 해당 배열의 첫요소 지점부터 저장시킵니다.
3) char 포인터를 이용한 문자열 |
char 포인터를 이용해서 문자열을 만들 수 있습니다.
#include <stdio.h>
int main()
{
char* str = "One of them";
printf("%s\n", str);
return 0;
}
포인터를 이용해서 문자열을 만들게 되면 배열처럼 접근할 수 없으며 값 수정을 할 수 없습니다.
(즉, 상수화가 된다는 소리입니다.)
4) 문자열 관련 함수(string.h) |
문자열 관련되어 헤더파일 "string.h"에는 많은 유틸리티 함수들이 존재합니다.
#include <stdio.h>
#include <string.h>
int main()
{
char str[50] = { 0, };
printf("문자열 입력: ");
scanf("%[^\n]s", str);
printf("문자열의 길이: %d \n", strlen(str));
return 0;
}
저 문자열의 길이를 출력한 strlen 함수입니다.
strlen(문자열) 형태로 사용가능하며 출력되는 값은 int형 값입니다.
#include <stdio.h>
#include <string.h>
int main()
{
char str[50] = { 0, };
printf("문자열 입력: ");
scanf("%[^\n]s", str);
char strCopy[50] = { 0, };
strcpy(strCopy, str);
printf("복사된 문자열 strCopy: %s\n", strCopy);
return 0;
}
다음은 문자열을 복사하는 strcpy 함수입니다.
strcpy(복사된_문자열을_저장할_배열, 복사할_문자열) 형태로 사용가능합니다.
strcpy의 취약점은 복사할 문자열보다 복사된 문자열을 저장할 배열이 적을 때 일어나는 경우인데요.
이것을 보완하고자 나온 함수인 strcpy_s가 있습니다.
#include <stdio.h>
#include <string.h>
int main()
{
char str[50] = { 0, };
printf("문자열 입력: ");
scanf("%[^\n]s", str);
char strCopy[50] = { 0, };
strcpy_s(strCopy, sizeof(strCopy) / sizeof(char), str);
printf("복사된 문자열 strCopy: %s\n", strCopy);
return 0;
}
strcpy_s(복사된_문자열을_저장할_배열, 저장할_길이, 복사할_문자열) 형태로 사용가능합니다.
저장될 길이를 정해줌으로써 오류를 잡아줍니다.
(strcpy_s는 C11에서 표준함수로 들어가게 되었으나 GCC에서는 아직 사용할 수 없습니다.)
#include <stdio.h>
#include <string.h>
int main()
{
char str1[50] = "Something Just ";
char str2[] = "Like This";
strcat(str1, str2);
printf("%s \n", str1);
return 0;
}
다음은 문자열을 붙여주는 strcat 함수입니다.
strcat(원래_문자열, 뒤에_덧붙여질_문자열) 형태로 사용가능합니다.
strcat또한 문자열 길이에 대한 오류가 있을 수 있기 때문에 strcat_s라는 함수가 나오게 되었습니다.
#include <stdio.h>
#include <string.h>
int main()
{
char str1[50] = "Something Just ";
char str2[] = "Like This";
strcat_s(str1, sizeof(str1) / sizeof(char), str2);
printf("%s \n", str1);
return 0;
}
strcat_s(원래_문자열, 저장할_길이, 뒤에_덧붙여질_문자열) 형태로 사용가능합니다.
저장될 길이를 정해줌으로써 오류를 잡아줍니다.
(strcat_s역시 C11에서 표준함수로 들어가게 되었으나 GCC에서는 아직 사용할 수 없습니다.)
#include <stdio.h>
#include <string.h>
void printResult(char *str1, char *str2)
{
int result = strcmp(str1, str2);
printf("str1: %s\n", str1);
printf("str2: %s\n", str2);
if (result == 0)
printf("두 문자열은 같음\n");
else if (result > 0)
printf("str1이 더 큼\n");
else
printf("str2가 더 큼\n");
printf("\n");
}
int main()
{
char str1[] = "One of Them";
char str2[] = "One of Them";
char str3[] = "one of them";
char str4[] = "ONE OF THEM";
printResult(str1, str2);
printResult(str1, str3);
printResult(str1, str4);
return 0;
}
다음은 문자열을 비교하는 strcmp 입니다.
strcmp(첫번째문자열, 두번째문자열) 형태로 사용가능하며
첫번째 문자열과 두번째 문자열이 같다면 0을,
첫번째 문자열이 두번째 문자열보다 크다면 0보다 큰 값을,
첫번째 문자열이 두번째 문자열보다 작다면 0보다 적은 값을 반환합니다.
// 소스 출처: http://en.cppreference.com/w/cpp/string/byte/strtok
#include <stdio.h>
#include <string.h>
int main(void)
{
char input[] = "A bird came down the walk";
printf("Parsing the input string '%s'\n", input);
char *token = strtok(input, " ");
while (token) {
printf("%s\n", token);
token = strtok(NULL, " ");
}
return 0;
}
다음은 문자열을 토큰단위로 잘라주는 strtok 입니다.
strtok(문자열, 토큰) 형태로 사용이 가능하며 토큰을 기준으로 문자열을 자르게 됩니다.
5) 문자열을 매개변수로 넘겨보자 |
문자열을 매개변수로 넘기는 방법은 배열을 매개변수로 넘기는 방법과 동일합니다.
#include <stdio.h>
#include <string.h>
void printResult(char *str1, char *str2)
{
int result = strcmp(str1, str2);
printf("str1: %s\n", str1);
printf("str2: %s\n", str2);
if (result == 0)
printf("두 문자열은 같음\n");
else if (result > 0)
printf("str1이 더 큼\n");
else
printf("str2가 더 큼\n");
printf("\n");
}
int main()
{
char str1[] = "One of Them";
char str2[] = "One of Them";
char str3[] = "one of them";
char str4[] = "ONE OF THEM";
printResult(str1, str2);
printResult(str1, str3);
printResult(str1, str4);
return 0;
}
위에서 봤던 strcmp 예제입니다.
다음시간에는 |
함수 포인터에 대해서 알아보도록 하겠습니다.
'Study > C언어' 카테고리의 다른 글
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 21 [다차원배열1 - 다차원배열의 기본(2차원, 3차원)] (0) | 2018.10.17 |
---|---|
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 20 [함수 포인터] (0) | 2018.10.17 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 17 [포인터] (0) | 2018.10.17 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 18 [배열과 포인터] (0) | 2018.10.17 |
처음하시는 분들을 위한 C언어 기초강의 시즌2 - 07 [입력문과 출력문(printf, scanf, scanf_s)] (0) | 2018.10.17 |