본문 바로가기
쿤즈 Dev/C

[C언어] 문자열과 배열 사이의 관계

by Koonz:) 2020. 12. 21.
728x90

C언어에서는 문자열에 해당하는 자료형 구조가 없습니다. 문자 한 글자에 해당하는 char, 정수형 자료형에 해당하는 int, 실수형 자료형에 해당하는 float, double입니다. 그래서 문자열을 표현하기 위해서는 배열이라는 것이 필요합니다.

 

 

이번 포스팅에서는 문자와 문자열 그리고 배열과의 관계에 대해서 알아보도록 하겠습니다.


문자, 문자열, 배열

우선 문자라는 것은 1byte 크기에 저장할 수 있는 글자를 의미합니다. 이러한 문자들을 차례대로 이어놓은 것을 우리는 문자열이라고 합니다. 하지만 C언어의 자료형에는 문자열에 해당하는 자료형이 없습니다. 그래서 배열을 알아야 합니다.

 

2020/10/26 - [쿤즈 Dev/C] - [C언어] 배열(Arrays) 사용 하는 방법

 

[C언어] 배열(Arrays) 사용 하는 방법

앞서 알아본 C언어의 사용법은 하나의 변수에 하나의 값을 저장하는 방법이었습니다. 다양한 변수들이 존재하지만 각 변수들에 하나의 값을 저장하고 있다보니 규칙적이거나 저장하려는 값이

koonsland.tistory.com

 

이러한 배열을 이용해서 문자에 해당하는 char 자료형을 배열로 만들어 놓은 것이 우리가 알고자 하는 문자열이 되는 것입니다. 다음 문자열을 예로 들어 보겠습니다.

char name[] = "Ironman";

변수 name은 char 자료형의 배열로 선언했고 Ironman 이라는 글자를 저장해 주었습니다. 따라서 배열변수 name은 8byte 크기의 변수가 생성되고 Ironman이라는 글자를 저장합니다. 왜 7byte가 아니고 8byte냐구요? 이유는 아래 그림을 통해서 보겠습니다.

각 배열의 인덱스 값에 순서대로 Ironman 이라는 글자가 저장되고 마지막에 '\0'이라는 글자가 포함되어 있는 것을 볼 수 있습니다. 이는 앞으로 NULL문자라고 합니다. 문자열이 끝났음을 알려주는 문자입니다. 만약 이 문자가 포함되어 있지 않다면 어디서 이 문자열이 끝났는지 알 수 없기 때문입니다.

 

우리 눈으로는 문자열의 끝을 알 수 있지만 컴퓨터가 인식할 수 없기 때문에 NULL문자를 통해서 컴퓨터는 문자열이 여기서 끝났음을 인식합니다.


문자열을 선언하는 방법

위에서도 잠깐 언급했지만 문자열을 선언하기 위해서는 배열을 사용합니다. 배열을 이용해서 선언하는 방법도 여러 가지가 있습니다. 이 중에서 편한 방법을 사용하면 됩니다.

char name[] = “Ironman”;
char name[8] = “Ironman”;
char name[] = {‘I’, ‘r’, ‘o’, ‘n’, ‘m’, ‘a’, ‘n’, ‘\0’};
char name[8] = {‘I’, ‘r’, ‘o’, ‘n’, ‘m’, ‘a’, ‘n’, ‘\0’};

배열의 크기를 정해서 선언하고 정의하는 방법, 배열의 크기를 정하지 않고 자동으로 설정되게 하는 방법입니다. 이때 주의할 점은 NULL문자를 포함해 주어야 하기 때문에 선언하고자 하는 문자열 크기에서 +1을 꼭 해주어야 합니다.

 

만약 NULL문자를 고려하지 않고 글자 수와 배열의 크기를 동일하게 했다 하더라도 오류가 발생하지 않을 수 있습니다. 다만 NULL문자를 찾기 때문에 원하는 글자 이외에 다른 글자(쓰레기 값)들이 포함되어 있을 수 있습니다.


문자열의 선언과 정의

문자열을 선언할 때에는 반드시 선언과 동시에 정의를 해줘야 합니다. 다음과 같이 선언하고 정의를 분리해준다면 오류를 발생시킬 수 있습니다.

char name[8];
name = "Ironman";

문자열을 나타내는 자료형이 없기 때문에 문자열을 한꺼번에 넣을 수 없기 때문입니다. 앞서 배열에서도 알아보았듯 배열에 값을 한꺼번에 넣을 수 없습니다. 그래서 문자열을 사용할 때에는 불편함이 존재할 수 있습니다.

 

대신 표준 입력 함수를 이용해서 문자열을 입력받아야 합니다. 표준 입력 함수는 scanf()입니다. 또 문자열을 처리하기 위한 함수들이 있습니다. 함수 이름 앞에 str이 붙은 함수들은 모두 문자열에 관련된 함수들입니다. 그럼 이러한 함수들은 어떻게 사용하는지 소스코드를 통해서 알아보도록 하겠습니다.


소스코드 1. string1.c

#include <stdio.h>

int main(int argc, const char* argv[]) {
    char name[10];

    printf("이름을 입력하세요.\n");
    scanf_s("%s", name, 10);
    printf("입력한 이름 : %s\n", name);

    return 0;
}

결과 1.1.

이름을 입력하세요.
koonsland
입력한 이름 : koonsland

소스코드 1에서는 문자 배열 변수 name을 선언하고 크기는 10으로 선언하였습니다. 그리고 여기에 저장할 값은 사용자로부터 받도록 했어요.

 

사용자로부터 문자를 입력받는 함수는 scanf_s() 함수를 사용하였습니다. scanf() 함수를 사용하면 아래와 같은 에러 메시지가 나타날 것입니다.

error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

안전하지 않은 함수이기 때문에 다른 함수를 사용하라는 메시지입니다. 이와 관련된 내용은 아래 링크에서 확인해주세요.

2020/08/06 - [쿤즈 Dev/C] - [C언어] 표준입력 표준출력 사용하기 (첫 프로그래밍 시작!)

 

[C언어] 표준입력 표준출력 사용하기 (첫 프로그래밍 시작!)

지금까지 C언어를 프로그래밍하기 위해서 여러가지 요소들을 확인해 보았습니다. 키워드와 식별자, 변수와 상수, 데이터 타입까지 이론적인 기초 부분을 알아보았습니다. 앞서 알아본 내용들을

koonsland.tistory.com

따라서 보완된 scanf_s() 함수를 사용하면 위와 같은 에러가 사라지면서 정상적으로 동작하는 것을 확인할 수 있습니다.

 

하지만 여기서 문제점이 발생합니다. scanf() 계열의 함수들은 모두 white space(space, newline, tab 등)가 포함된 문자열이 있다면 white space 문자 앞까지만 인식합니다. 예제를 보겠습니다.

결과 1.2.

이름을 입력하세요.
koons land
입력한 이름 : koons

입력한 koons land는 가운데 space가 섞여있습니다. 그래서 name 변수에는 koons 까지만 저장되는 것입니다. 이를 보완하기 위해 다른 함수를 사용할 수 있습니다.


소스코드 2. fgets.c

#include <stdio.h>

int main(int argc, char* argv)
{
	char name[10];

	printf("이름을 입력하세요.\n");
	fgets(name, sizeof(name), stdin);
	printf("이름 : %s\n", name);

	return 0;
}

결과 2.

이름을 입력하세요.
koons land
입력한 이름 : koons lan

이번에는 scanf_s() 함수 대신 fgets() 함수를 사용했습니다. 이 함수는 3개의 parameter를 받습니다. 첫 번째는 문자열을 입력받아 저장할 포인터 변수, 두 번째는 크기, 세 번째는 무엇으로부터 입력받을지를 넣어줍니다. 이 소스에서는 표준 입력장치(키보드)로부터 입력받을 예정이므로 stdin이라는 값을 넣어주었습니다.

 

만약 stdin이 아닌 파일에서 입력받을 경우에는 추후 등장할 FILE 포인터 변수를 사용하면 됩니다.

 

여기서 소스코드 2는 name 변수의 크기가 10입니다. 하지만 입력한 값도 10글자입니다. 분명 마지막엔 NULL값이 포함되어야 한다고 했죠. 그래서 9글자까지만 저장되고 마지막엔 NULL 값이 들어가서 'd'라는 문자가 빠지게 되는 것입니다.


이번 포스팅에서는 문자, 문자열, 그리고 배열과의 관계에 대해서 알아보았습니다. C언어는 문자열을 입력받을 자료형이 없기 때문에 문자 배열을 이용해서 문자열을 처리합니다. 그리고 이는 포인터 변수를 사용해서 변수에 접근하고 값을 가져오고, 혹은 값을 수정할 수 있습니다.

 

데이터의 대부분은 문자열이 많기 때문에 이 부분도 사용이 익숙해지면 C언어를 마스터하는데 더 도움이 되실 겁니다. 다음엔 문자열을 쉽게 사용할 함수에 대해서 알아보도록 하겠습니다.

댓글