728x90

<문자열>

1. 문자열 개요

1) 문자열(string)
- 연속적으로 나열된 문자들의 묶음
- 문자열은 문자배열을 사용하여 저장

2) 문자열 표현
큰 따옴표("")로 감싸서 나타냄
- "Hello", "Program"
문자는 작은 따옴표('')로 감싸서 표현

3) 문자열 입출력
- scanf, printf에서 문자열 단위 입출력 지원
- 서식 문자: %s

2. 문자열 저장 및 기본 입출력

1) 문자열 표현 예시
- 일반 문자열: "Hello", "Sejong"
- 공백 문자열: " " (큰 따옴표 사이 공백)
- 길이가 0인 문자열: "" (사이에 아무것도 없음)

2) 큰 따옴표와 작은 따옴표의 차이
- "A" 는 문자열
- 'A'는 문자

3) 문자열 저장 및 초기화
- C언어에서는 문자 배열에 문자열 저장
- 문자 배열 선언 및 초기화 예시

char str1[8] = "Hello"; // 배열 크기 지정
char str2[] = "Hello"; // 배열 크기 미지정, 초기화 값에 의해 크기 결정


- 문자열로 초기화 하는 것은 선언 시에만 가능

4) 널(null) 문자
문자열의 끝을 의미하는 특수문자 '\0'으로 표현
널문자의 아스키 코드 값은 0, 즉 '\0' == 0
- 문자열을 처리하는 기준이 되는 매우 중요한 요소
문자열(%s) 는 항상 맨 마지막에 널 문자를 포함하고 있음

<< 문자와 문자열의 차이 >>
- 문자 'A' = A
- 문자열 "A" = 'A' + '\0'
- char str[] = "Hello";  == char str[] = {'H', 'e', 'l', 'l', 'o', '\0'}
따라서 문자배열에 문자열을 저장하기 위해서는 배열의 크기가 문자열의 길이보다 하나 더 커야 됨

5) C언어에서 문자열의 기준
널 문자 까지의 문자들의 묶음을 지칭
- 주의) 배열의 크기와 관계없음 >> 배열은 단순히 저장 공간으로서의 역할
- 문자열의 끝은 배열의 크기가 아니라 널문자에 의해 결정
- 입출력을 비롯한 모든 문자열 처리의 기준

6) printf() 함수를 이용한 문자열 출력
- 문자열을 하나의 단위로 취급
- 서식 지정자: %s
- 인자: 문자열의 시작주소 (보통은 문자열의 이름)

7) 출력 시 널 문자의 역할
- 배열에서 초기화가 명시되지 않은 원소는 0(즉 '\0')으로 초기화 됨
- 널 문자는 화면에 공백처럼 출력된다. 그러나 공백문자와는 다르다.
- 인자로 전달된 주소의 문자부터 널 문자 전까지 출력한다.
- 배열 크기만큼 출력하는 것이 아니다.
- printf 함수는 배열의 크기를 모른다.

>> 예시1. 문자열 하나하나 요소 출력

char str[20] = "Hello World";
for (int i = 0; i<20; i++){
	printf("%c", str[i]);
}
printf("!!\n");



결과:
Hello World         !!
// 공백이 나타나는 이유는 널 문자를 출력하면 공백처럼 출력되기 때문

>> 예시2. 문자열 한번에 출력

char str[20] = "Hello World";
printf("%s!!", str);


결과:
Hello World!!
// 공백이 나타나지 않는 이유는 널 문자 전까지만 인식해서 출력하기 때문

8) scanf() 함수를 이용한 문자열 입력
- 서식 지정자: %s
- 인자: 문자열을 저장할 시작 주소(보통 배열의 이름)
- 사용자로부터 입력받은 문자열을 인자로 전달된 주소부터 차례로 저장
- 개행문자, 공백문자, 탭 문자 직전까지 하나의 문자열로 인식
- 마지막에 널 문자를 자동으로 추가
- 따라서 문자열은 널문자를 저장할 충분한 공간이 확보되어 있어야 함

3. 문자열과 포인터

1) 문자형 포인터를 활용한 문자열 처리문
- 문자형 포인터를 선언하고 문자열 "Hello"를 가리키도록 초기화
- str에 "Hello"의 시작주소가 저장되어 있으므로, printf의 %s 서식을 이용해 출력

char *str = "Hello";
printf("%s!!\n", str);



2) 문자 배열과 문자열 상수
- "Hello"는 문자열 상수로, 사용자 프로그램에서 변경 불가능
- 반면 str은 사용자 변수로 값을 변경 할 수 있음
"Hello"의 값을 변경할 수는 없지만,
그냥 애초에 "World"가 저장되는 새로운 주소로 str을 변경할 수는 있음
- str이 해당 문자열을 가리키는 것이 아닌, 해당 문자열의 주소를 가리키기 때문

char *str = "Hello";
str[0] = 'h' // 변경 불가능
str = "World"; // 변경 가능



- 문자 배열로 선언하면 문자 배열 하나하나에 각 문자가 저장
>> 각각의 요소 변형 가능, 전체의 주소 변경 불가능

char str1[6] = "Hello";



- 문자형 포인터로 선언하면 불변하는 문자열 상수("Hello")의 시작 주소가 문자형 포인터에 저장 
>> 각각의 요소 변경 불가능, 전체의 주소 변경 가능

char str2[6] = "Hello";



4. 문자열의 배열

1) 다수의 문자열 처리하기

(1) 문자 배열을 여러개 사용

char num0[5] = "zero";
char num1[5] = "one";
char num2[5] = "two";


>> 문자열이 많아지면 불편

(2) 문자열의 배열 >> 2차원 문자 배열 이용

char num[3][5] = {"zero", "one", "two"};


>> num[0], num[1], num[2]의 자료형은 char *
>> 상수영역은 변경 불가능(문자 부분 변경 불가능)

(3) 문자형 포인터를 여러개 사용

char *pnum0[5] = "zero";
char *pnum1[5] = "one";
char *pnum2[5] = "two";


>> 문자열이 많아지면 불편
>> 상수영역은 변경 불가능(문자 부분 변경 불가능)
>> 입력을 받는 경우 사용 불가능 (해당 문자의 길이를 알아야 메모리를 할당할 수 있기 때문)

(4) 문자형 포인터 배열

char *pnum = {"zero", "one", "two"}


>> 상수영역은 변경 불가능(전체 변경 불가능)
>> 아예 새로운 포인터 배열을 생성해야 변경 가능
>> 입력을 받는 경우 사용 불가능 (해당 문자의 길이를 알아야 메모리를 할당할 수 있기 때문)

5. 문자열 및 문자 처리 함수

1) 문자열 처리 표준 함수
- C언어에서는 문자열 처리에 관련된 다양한 표준 함수 제공
- 대부분 <string.h> 헤더파일에 함수의 원형 선언되어 있음
#include <string.h>
- 대부분 문자열 처리 함수의 코드를 작성하는 것은 어렵지 않지만, 
이미 구현되어 있는 표준 함수를 사용하는 것이 편리

2) 문자열의 길이 구하기

(1) 직접 구현

char str[20] = "Hello World";
int length = 0;
while (str[length]){
	length++;
}
printf("Length: %d\n", length);



(2) strlen() 함수 사용
- 원형: unsigned int strlen(char *s)
- 기능: 문자열 s의 길이 반환

#include <stdio.h>
#include <string.h> // strlen() 함수가 선언된 헤더파일

int main(){
	char str[20] = "Hello World";
	printf("Length: %d\n", strlen(str));
	return 0;
}



3) 문자열 복사하기

(1) strcpy() 함수 사용
- 원형: char *strcpy(char *dest, char *src)
- 기능: dest의 공간에 src의 문자열 복사(문자열 대입), src는 변화 없음
- dest의 공간이 src의 문자열의 길이+1 이상이어야 가능(널문자 때문)

#include <stdio.h>
#include <string.h> // strcpy() 함수가 선언된 헤더파일

int main(){
	char str[20] = "Hello";
	strcpy(str, "hi");
	printf("str: %s\n", str);
	return 0;
}



// str = {'H', 'e', 'l', 'l', 'o', '\0'} 에서 str = {'h', 'i', '\0', 'l', 'o', '\0'} 로 변경

(2) strncpy() 함수
복사할 문자열의 길이를 지정하는 함수
- 원형: char *strncpy(char *dest, char *src, size_t count)

4) 문자열 접합

(1) strcat() 함수 사용
- 원형: char *strcat(char *dest, char *src)
- 기능: 문자열 dest 뒤에 src의 문자열 접합. src는 변화 없음
- 문자열 dest의 널 문자를 빼고 src 접합
- dest에 접합결과를 저장하기에 충분한 공간이 할당되어 있어야 함

#include <stdio.h>
#include <string.h> // strcat() 함수가 선언된 헤더파일

int main(){
	char str[20] = "Hello";
	strcat(str, "hi");
	printf("str: %s\n", str);
	return 0;
}



(2) strncat() 함수
접합할 문자열의 길이를 지정하는 함수
- 원형: char *strncat(char *dest, char *src, size_t count)

5) 문자열 비교하기

(1) strcmp() 함수 사용
- 원형: int strcmp(char *lhs, char *rhs)
- 기능: 사전 순으로 lhs와 rhs를 비교하여,
문자열 lhs < rhs 이면 음수, 
문자열 lhs == rhs 이면 0, 
문자열 lhs > rhs 이면 양수 반환
- 어떤 음수, 어떤 양수를 반환하는 지는 컴파일러마다 다를 수 있음
- 문자열 비교는 첫 문자부터 순서대로 비교한다

(2) strncmp() 함수
비교할 문자열의 길이를 지정하여 비교
- 원형: int strncmp(char *lhs, char *rhs, int n)
- 비교대상의 문자열에서 처음 n개 까지만 비교

6) 10진수로 표현된 문자열을 수로 변환
int atoi(char *str) : int형으로 계산하여 반환
long atol(char *str) : long형으로 계산하여 반환
double atof(char *str) : double형으로 계산하여 반환

7) 주요 문자열 처리 함수 요약
- strlen(s) : 문자열의 길이 반환
- strcpy(s1, s2) : 문자열 s1에 s2 복사
- strcat(s1, s2) : 문자열 s1의 끝에 s2를 접합
- strcmp(s1, s2) : 문자열 s1과 s2를 사전순으로 비교
- atoi(s) : 문자열 s를 int 형으로 계산하여 반환
- atol(s) : 문자열 s를 long 형으로 계산하여 반환
- atof(s) : 문자열 s를 double 형으로 계산하여 반환

6. 문자열 및 문자 입출력

1) 입출력 함수

(1) printf()와 scanf(): 다양한 기능을 가진 범용 입출력 함수
>> 함수의 크기가 크고, 속도 느림

(2) 문자열 및 문자 특화 입출력 함수
- 문자열 입출력 함수: puts, gets (gets_s, fputs)
- 문자 입출력 함수: putchar, getchar

- C언어에서는 문자열과 문자에 특화된 입출력 함수 제공
>> 속도가 빠르고, 문자 또는 문자열 입출력에 적합
- 위 함수들은 모두 <stdio.h>에 선언되어 있음

2) 문자열 출력 함수 : int puts(char *str)
- str이 가리키는 문자열을 화면에 출력하고 마지막에 '\n' 출력
- 반환 값: 출력에 성공하면 음수가 아닌 값, 실패하면 EOF

3) 문자열 입력 함수
(1) char *gets(char *s)
- 사용자로부터 문자열을 입력받아, s가 가리키는 메모리 영역에 저장하고, 포인터 s를 리텀
엔터('\n')가 입력될 때까지 입력된 모든 문자들을 저장
마지막에 입력된 '\n'은 무시하고, 맨 뒤에 '\0'를 붙임
- 문자열을 저장할 충분한 메모리 공간이 확보되어 있어야 함

(2) gets_s(char *s, int size)
- gets_s() 함수는 gets() 함수의 보안 버전으로, 문자열을 저장할 배열 크기를 인자로 전달
- 보안 상의 문제로 gets() 함수는 표준에서 제외되고, gets_s() 함수가 표준에 추가됨
- Visual Studio의 경우 2015버전부터 gets() 지원 안함
- gcc의 경우 gets() 만 지원

(3) fgets(char *s, int size, File *pfile)
- 대안의 대안으로 fgets() 함수 사용
- 문자열을 저장할 배열의 주소, 문자열을 저장할 배열 크기, 파일의 포인터까지 인자로 전달
개행 문자('\n')도 문자열에 저장

4) 문자 입출력 함수
(1) 문자 출력 함수 : int putchar(int c) 
- 변수 c에 저장된 문자를 화면에 출력
- 성공하면 문자 반환, 실패하면 EOF 반환 

(2) 문자 입력 함수 : int getchar(void) 
- 사용자로부터 입력된 문자 반환
- 성공하면 문자 반환, 실패하면 EOF 반환 

728x90

+ Recent posts