문자를 저장하는 배열
목차
- char형 배열
- 문자열 대입 함수 strcpy
- 문자열 입출력 함수 puts, gets
1. char형 배열
자, 저번에 char형 배열을 간단하게 짚고 넘어갔죠.
char형 배열은 문자열을 저장합니다. 그리고 제일 끝에는 널 문자 ( \0 )이 들어가죠.
한번 선언해 봅시다.
char str[10] = "RoadMew"; 로 선언하면 배열은 다음과 같이 저장됩니다.
R | o | a | d | M | e | w | \0 | \0 | \0 |
보시면 여분의 남은 공간에는 전부 널 문자 \0이 들어갑니다.
한번 문자열을 하나하나 출력해서 증명해볼까요? 반복문을 응용해 보세요.
#include <stdio.h>
int main(void)
{
char str[10] = "RoadMew";
for (int i = 0; i < 10; i++)
{
printf("%c\n", str[i]);
}
printf("출력 종료");
return 0;
}
출력은 다음과 같습니다.
R
o
a
d
M
e
w
출력 종료
물론 원한다면 문자열로 초기화하지 말고 문자를 통해 일반적인 배열처럼 초기화할 수 있어요.
하지만 너무 귀찮으니 그냥 문자열 상수로 초기화합시다.
이전에도 말했지만, 널 문자 \0은 문자열의 끝을 의미합니다.
scanf 함수를 이용해 문자열을 받을 때도 자동으로 널 문자가 추가됩니다.
한번 테스트를 해 보죠. scanf 함수로 저 문자열 배열을 덮어써볼까요..?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char str[10] = "RoadMew";
scanf("%s", str);
printf("출력 : %s\n\n", str);
for (int i = 0; i < 10; i++)
{
printf("%c\n", str[i]);
}
printf("출력 종료");
return 0;
}
좋아요. 출력을 한번 확인해볼까요
apple
출력 : apple
a
p
p
l
e
w
출력 종료
흠, 문자열 상태가 좀 이상합니다.
이건 이유가 있는데, scanf는 문자열의 널 문자 \0을 하나만 추가하기 때문이에요.
설명하자면 다음과 같아요.
R | o | a | d | M | e | w | \0 | \0 | \0 |
처음 str이 초기화될 때는 다음과 같이 초기화됩니다.
그리고 scanf로 값을 받아서 수정하면..
a | p | p | l | e | \0 | w | \0 | \0 | \0 |
딱 저 부분까지만 수정됩니다.
아무튼, 이런 데 사용되는 char형 배열을 선언할 때 주의점이 몇 가지 있어요. 그것만 알아봅시다.
일단, 배열의 크기를 되도록 넉넉하게 잡아야 하며, 최소 개수는 문자열의 길이보다 하나 더 길어야 해요.
그리고 문자열을 여러개 저장하려면 2차원 배열을 선언해야 하는데.. 그건 나중에 알아봅시다.
2. 문자열 대입 함수 strcpy
이전에 배열에 대해 배울 때, <string.h>라이브러리를 이용해서 strcpy로 수정할 수 있는 방법이 있다고 말했습니다.
한번 이걸 사용해 보도록 하죠.
strcpy 함수의 기본 사용법은 다음과 같습니다.
strcpy(저장될 배열, 저장할 문자열);
굳이 배열과 문자열로 나눈 이유는, strcpy의 첫 번째 부분은 배열만 받을 수 있지만 두 번째 부분은 문자열 상수도 가능하기 때문이에요.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[10] = "RoadMew";
char null[10] = { 0 };
strcpy(str, "Cat");
printf("%s\n", str);
strcpy(null, str);
printf("%s\n", null);
return 0;
}
자, 한번 출력을 받아봅시다.
Cat
Cat
보시면 scanf가 없음에도 #define _CRT_SECURE_NO_WARNINGS가 들어가 있는데, C의 문자열 관련 함수들은 대부분 저게 필요합니다. 아무래도 구식 프로그래밍 언어인지라..
strcpy가 Cat을 str에 대입하고, 이후 str을 null에 대입합니다.
이전에 말했던 대로, strcpy("Cat", "Dog")는 불가능합니다.
3. 문자열 입출력 함수 puts, gets
char 배열에 문자열은 scanf 함수를 이용해 받았습니다.
흠, 한번 다음과 같이 해 볼까요?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char str[30] = { 0 };
printf("입력 : ");
scanf("%s", str);
printf("출력 : %s\n", str);
return 0;
}
한번 다음과 같이 입력해 봅시다.
입력 : Hello World!
출력 : Hello
음...
scanf 함수는 char형 배열에 문자열을 입력할 수는 있지만, 중간에 빈칸이 있으면 받을 수 없습니다.
즉, scnaf 함수는 "단어"만 받을수 있다는 겁니다.
흠, "문장"을 받을 수 있는 방법은 없을까요?
문장을 받기 위해 문자열 함수가 존재합니다. 바로 gets 함수입니다.
gets 함수와 짝으로 puts 함수 또한 존재합니다. 한번 사용해보죠.
gets 함수의 구조는 다음과 같습니다.
gets(문자열);
심플하죠?
#include <stdio.h>
int main(void)
{
char str[30] = { 0 };
printf("입력 : ");
gets(str);
printf("출력 : %s\n", str);
return 0;
}
출력은 다음과 같습니다.
입력 : Hello World!
출력 : Hello World!
흠, 바로 puts 함수도 사용해 보죠. (자꾸 pust라고 쓰네..)
puts 함수의 구조는 다음과 같습니다.
puts(문자열);
심플하죠?
이 함수는 문자열을 출력합니다.
즉, printf("%s\n",str);과 동일하다는 거네요.
#include <stdio.h>
int main(void)
{
char str[30] = { 0 };
printf("입력 : ");
gets(str);
puts(str);
return 0;
}
출력은 다음과 같습니다.
입력 : Hello World!
Hello World!
굳이 한 칸 떨어진 이유는, 위에서도 잠깐 나왔지만 puts 함수는 \n을 자동으로 포함하기 때문입니다.
그래서 puts 함수를 이용해서는 문자열을 연속해서 출력할 수는 없어요.
그리고 몇 가지 주의점이 있는데, gets 함수는 배열의 크기를 검사하지 않으므로 너무 긴 문자열이 입력되면 배열을 벗어나 이상한 메모리 영역을 침범할 수 있어요. scanf 함수는 크기가 길어지면 잘라버리는 반면에 말이죠..
마지막으로, 널 문자를 넣지 않으면...
조심하도록 합시다.