본문 바로가기

C언어/자료구조

7-1장 문자열의 기본

1. 문자열 (string)

 

- 문자의 나열 

 

2. 문자열 리터럴(string literal)

 

- 문자 나열을 2개의 큰따옴표(")로 묶은 것 

- 문자열 안의 문자는 메모리 공간에 연속으로 배치 

- 컴퓨터는 문자열 리터럴의 끝을 나타내기 위해 널문자(null character) 추가 

 

- 문자열 리터럴의 자료형은 char형 배열 

- 문자열 리터럴의 표현식을 평가하여 얻는 자료형은 char*형이고 그 값은 첫 번째 문자에 대한 포인터 

 

- 문자열 리터럴의 메모리 영역 기간은 정적 메모리 영역의 기간

 -> 프로그램 시작부터 끝까지 메모리 영역이 유지

 

- 문자열 리터럴은 상수의 성질을 가짐 

 -> 문자열 리터럴이 저장된 메모리 영역에 값 대입 불가 

 

- 문자열 안의 문자를 16진수와 2진수로 출력

//문자열 안의 문자를 16진수와 2진수로 출력
#include <stdio.h> 
#include <limits.h>

//문자열 s 안의 문자를 16진수와 2진수로 출력하는 함수 
void str_dump (const char *s) 
{
	for(;*s!='\0';s++) {
		printf("%c%0*X",*s,(CHAR_BIT+3)/4,*s);
		for(int i=CHAR_BIT-1; i<=0; i--)
			putchar(((*s>>i)&1U)? '1':'0');
		putchar('\n');
	}
}

int main()
{
	str_dump("STRING");
	return 0;
}

이게 맞나..?

 

3. 배열에 문자열 저장

 

- 문자열 값을 char형 배열에 저장하면 자유롭게 값을 꺼내고 쓸 수 있음

- 널문자는 문자열의 끝을 나타냄

- st[5]부터 어떤 문자를 대입해도 널 문자까지만 문자열이라고 인식 

 

- 문자열을 배열로 저장해서 출력

//문자열을 배열로 저장해서 출력
#include <stdio.h> 

int main()
{
	char st[8];
	st[0] = 'A';
	st[1] = 'B';
	st[2] = 'C';
	st[3] = 'D';
	st[4] = '\0';
	printf("문자열 st에는 \"%s\"가  들어 있습니다.\n",st);
	
	return 0;
		
}

 

- 문자열 초기화 

char st[10] = {'A','B','C','D','\0'};
char st[10] = "ABCD";

 

- 문자열을 배열에 초기화하며 선언

//문자열을 배열에 초기화하며 선언
#include <stdio.h> 

int main()
{
	char st[8]="ABCD";
	printf("문자열 st에는 \"%s\"가 들어있습니다.\n",st);
	
	return 0;
}

 

4. 포인터로 문자열 나타내기

 

- 선언한 char*형 포인터 pt는 초기화 요소로 문자열 리터럴 "12345"fmf wna

- 포인터 pt는 "12345"가 들어 있는 메모리 영역의 첫 번째 문자 '1'을 가리키며 초기화 

- 포인터 pt는 마치 배열인것 처럼 행동

- '1','2','3','4','5'는 pt[0],pt[1],pt[2],pt[3],pt[4]의 인덱스로 접근 가능

- 포인터로 표현한 문자열은 배열에 저장한 문자열보다 더 많은 메모리 영역을 차지 

char st[] = "12345"; //배열에 의한 문자열의 크기는 6바이트 
char *pt = "12345"; //포인터에 의한 문자열의 크기는 sizeof(char*) + 6바이트

 

- 두 포인터값을 서로 교환하는 함수 프로그램

 -> 포인터(s1,s2)의 주소를 받아야 하기 때문에 char**형으로 정의 (포인터를 가리키는 포인터)

//두 포인터값을 서로 교환하는 함수 프로그램
#include <stdio.h> 

//두 포인터를 서로 교환하는 함수 
void swap_ptr (char **x, char **y) 
{
	char *tmp = *x;
	*x = *y;
	*y = tmp;
}

int main()
{
	char *s1 = "ABCD"; //s1은 "ABCD"의 첫글자 'A'를 가리킴
	char *s2 = "EFGH"; //s2는 "EFGH"의 첫글자 'E'를 가리킴
	
	printf("포인터 s1은 \"%s\"를 가리킵니다.\n",s1);
	printf("포인터 s2은 \"%s\"를 가리킵니다.\n",s2);
	
	swap_ptr(&s1,&s2);
	
	puts("\n포인터 s1와 s2의 값을 서로 교환했습니다.\n");
	
	printf("포인터 s1은 \"%s\"를 가리킵니다.\n",s1);
	printf("포인터 s2은 \"%s\"를 가리킵니다.\n",s2);
	
	return 0;
	
}

 

 

5. 문자열의 길이 

 

- 문자열의 첫문자부터 널 문자까지 선형 검색

- 널 문자의 인덱스는 문자열의 길이와 같음

 

- 문자열의 길이를 구하는 프로그램

//문자열의 길이를 구하는 프로그램
#include <stdio.h> 

int str_len(const char *s)
{
	int len = 0;
	
	while(s[len])
		len ++;
	return len;
}

int main()
{
	char str[256];
	printf("문자열:");
	scanf("%s",str);
	printf("이 문자열의 길이는 %d입니다.\n",str_len(str));
	
	return 0;
}

 

5.1 strlen 함수 

 

- c언어 표준 라이브러리에 있는 문자열의 길이를 구하는 함수 

- size_t strlen(const char *s)

- s가 가리키는 문자열의 길이를 반환

- 반환값 size_t형

 (sizeof 연산자가 생성하는 결과를 나타내는 부호 없는 정수형)

 

 

6. 문자열에서 문자 검색

 

- 문자열에서 문자를 검색하는 프로그램

//문자열에서 문자를 검색하는 프로그램
#include <stdio.h> 

int str_chr(const char *s, int c)
{
	int i=0;
	c = (char)c;
	while(s[i]!=c) {
		if(s[i] == '\0')
			return -1; //검색 실패 
		i++; 
	}
	return i; //검색 성공  
}

int main()
{
	char str[128]; //이 문자열에서 탐색
	char tmp[128];
	int ch; //검색할 문자  
	int idx;
	
	printf("문자열:");
	scanf("%s",str);
	
	printf("검색할 문자:");
	scanf("%s",tmp); //먼저 문자열로 검색할 문자를 읽음
	ch = tmp[0]; //첫 번째 문자를 검색할 문자로 지정
	
	if((idx = str_chr(str,ch)) == -1)  //처음 나오는 문자를 검색
		printf("문자 %c는 문자열에 없습니다.\n",ch);
	else
		printf("문자 %c는 %d번째에 있습니다.\n",ch,idx+1); 
		
	return 0;
 }

 

 

6.1 strchr함수와 strrchr함수 

 

strchr함수 

- char *strchr(const char *s, int c);

- s가 가리키는 문자열에서 가장 앞쪽에 있는 c를 찾음

- 찾은 문자에 대한 포인터 반환, 문자가 없으면 널 포인터 반환

 

strrchr 함수 

- char *strrchr(const char *s, int c);

- s가 가리키는 문자열에서 가장 뒤쪽에 있는 c를 찾음

- 찾은 문자에 대한 포인터 반환, 문자가 없으면 널 포인터 반환

 

 

7. 문자열의 대소관계

 

strcmp 함수 

- int strcmp(const char *s1, const char *s2)

- s1와 s2가 가리키는 문자열의 대소관계 비교

 처음부터 순서대로 한 문자씩 unsigned char형 값으로 비교 

- 같으면 0 s1이 크면 양수, s2가 크면 음수 반환

//문자열을 비교하는 프로그램
#include <stdio.h> 

//두 문자열 s1과 s2를 비교하는 함수 
int str_cmp(const char *s1, const char *s2) 
{
	while(*s1 == *s2) {
		if(*s1 == '\0') //같음
			return 0;
		s1++;
		s2++; 
	}
	return (unsigned char)*s1 - (unsigned char)*s2;
}

int main()
{
	char st[128];
	puts("\"ABCD\"와 비교합니다.");
	puts("\"XXXX\"면 종료합니다.");
	while(1) 
	{
		printf("문자열 st:");
		scanf("%s",st);
		if(str_cmp("XXXX",st) == 0)
			break;
		printf("str_cmp(\"ABCD\",st)=%d\n",str_cmp("ABCD",st));
	}
	
	return 0;
}

 

strncmp 함수 

 

- 3번째 인수로 지정한 문자열의 길이만큼만 비교 가능 

- 널문자가 없는 '문자 배열'간의 비교 가능 

- int strncmp(const char *s1, const char *s2, const char *s2 size_t n);

 

- s1,s2가 가리키는 문자 배열에서 n번째 문자까지의 대소 관계를 비교 

 처음부터 순서대로 한 문자씩 unsigned char형 값으로 비교

 널 문자 이후의 비교는 하지 않음

//문자열을 비교하는 프로그램 (strncmp 함수 사용)
#include <stdio.h> 
#include <string.h>

int main()
{
	char st[128]; 
	puts("\"STRING\"의 처음 3개의 문자와 비교합니다.");
	puts("\"XXXX\"를 입력하면 종료합니다.");
	while(1) {
		printf("문자열 st:");
		scanf("%s",st);
		if(strncmp("XXXX",st,3)==0)
			break;
		printf("strncmp(\"STRING\",st,3)=%d\n",strncmp("STRING",st,3));
	}
	
	return 0;
}

'C언어 > 자료구조' 카테고리의 다른 글

7 -3장 KMP법  (0) 2023.08.02
7-2장 브루트 - 포스법  (0) 2023.08.01
6-9장 도수 정렬  (0) 2023.08.01
6-8장 힙 정렬  (0) 2023.08.01
6-7장 병합 정렬  (0) 2023.07.31