티스토리 뷰

2021.02.16.화

<string.h>

✔  문자열과 관련된 함수를 가진 헤더 파일로, 문자열 관련 함수를 사용하기 위해 반드시 전처리할 것.

✔  아래는 문자열과 관련된 자주 사용되는 함수의 정리.

 

 

1. 문자열 복사 함수
   strcpy(str1, str2)    str1에 str2의 문자열을 복사
   strncpy(str1, str2, n)    str1에 str2의 문자열을 n만큼 복사
#include <stdio.h>
#include <string.h> //문자열 관련 함수를 가진 헤더파일

int main(void)
{
  //strcpy 예제
  char str1[10] = "apple";
  printf("%s\n", str1);		//apple
  strcpy(str1,"banana");
  printf("%s\n", str1);		//banana

  //strncpy 예제
  char str2[20] = "hello world";
  printf("%s\n", str2);		//hello world
  strncpy(str2,"clang", 2);
  printf("%s\n", str2);		//clllo world
  strncpy(str2,"hello", 5);
  printf("%s\n", str2);		//hello world
  
  
  return 0;
}   

 

 

 

2. 문자열 비교 함수
   strcmp(str1, str2)    아스키 코드를 기준으로 str1과 str2의 순서 비교
   strcnmp(str1, str2, n)    아스키 코드를 기준으로 str1과 str2의 순서를 n만큼 비교
#include <stdio.h>
#include <string.h>

int main(void)
{
  //strcmp 예제    
  char str1[10] = "apple";
  char str2[10] = "banana";
  printf("%d\n", strcmp(str1,str2));	//apple과 banana를 비교	→ -1 (음수)
  printf("%d\n", strcmp(str1,str1));	//apple과 apple을 비교	→ 0 
  printf("%d\n", strcmp(str2,str1));	//banana와 apple을 비교 → 1 (양수)
  
  return 0;
}   

✔  str1이 str2보다 아스키코드를 기준으로 앞에 있다면 음의 정수를 반환.

✔  str1에 저장된 문자열과 str2에 저장된 문자열이 동일하다면 0 을 반환.

✔  str1이 str2보다 아스키코드를 기준으로 뒤에 있다면 양의 정수를 반환.

✔  비교 대상이 동일해도 인자 입력 순서에 따라 비교의 기준이 다르기 때문에 다른 값을 반환받을 수도 있다.

#include <stdio.h>
#include <string.h>

int main(void)
{
  //strncmp 예제    
  char str1[20] = "applejuice";
  char str2[20] = "applejam";
  printf("%d\n", strncmp(str1,str2,5)); //str1의 apple과 str2의 apple을 비교 		→ 0 
  printf("%d\n", strncmp(str1,str2,7)); //str1의 appleju와 str2의 appleja을 비교 	→ 20 (양수)
  printf("%d\n", strncmp(str2,str1,7)); //str2의 appleja와 str1의 appleju을 비교 	→ -20(음수)
  
  return 0;
}   

✔  str1과 str2에 저장된 문자열을 n개 비교. 반환 값의 원리는 strcmp()와 동일하다.

 

 

 

3. 문자열 검색 함수
   strstr(str1, str2)    str1에서 str2과 일치하는 문자열이 있는지 확인하고 포인터 반환
   strchr(str, c)    str의 내부에 문자 c가 존재하는지 확인하고 포인터 반환 (앞에서부터 확인)
   strrchr(str, c)    str의 내부에 문자 c가 존재하는지 확인하고 포인터 반환 (뒤에서부터 확인)
#include <stdio.h>
#include <string.h>

int main(void)
{
    //strstr 예제1
    char* str1 = "applejam";
    char* p1 = strstr(str1,"jam");    
    
    if(p1!=0) {
       printf("%s 에는 jam이 포함되어 있습니다\n",str1);
       printf("p1이 가리키는 주소 \t: %p\n",p1);	//0x4006dd
       printf("str1이 가리키는 주소 \t: %p\n",str1);	//0x4006d8
    }else{
       printf("%s 에는 jam이 포함되어 있지 않습니다\n",str1);
    }
    
    //strstr 예제2
    char* str2 = "applejam";
    char* p2 = strstr(str2,"juice");    
    
    if(p2!=0) {
       printf("%s 에는 juice가 포함되어 있습니다\n",str2);
    }else{
       printf("%s 에는 juice가 포함되어 있지 않습니다\n",str2);
    }
  return 0;
}   

✔  strstr() 함수는 두 번째 인자의 값이 첫 번째 인자 내부에 없다면 null을 반환하므로 if문을 사용해 확인하는 과정이 필요하다.

✔  동일한 문자열을 가지고 있다면 해당 문자열의 포인터를 반환한다.

✔  예제 1에서 p1에 저장된 주소가 0x4006dd 인 것은 jam이 저장된 문자열의 주소, j가 저장된 주소를 반환했기 때문이다.

 

a p p l e j a m
0x4006d8 0x4006d9 0x4006da 0x4006db 0x4006dc 0x4006dd 0x4006de 0x4006df

 

✔  위 개념을 이해하기 어렵다면 우측 게시글 확인을 추천  [참고 링크] [CS50 5주차] 3-5. 문자열

 

 

 

4. 문자열을 이어 붙이는 함수
   strcat(str1, str2)    str1의 뒤에 str2를 이어붙이고 str1에 저장
   strncat(str1, str2, n)    str1의 뒤에 str2의 문자 n개를 이어붙이고 str1에 저장
#include <stdio.h>
#include <string.h>

int main(void)
{
  //strcat 예제
  char str1[10] = "apple";
  char str2[10] = "jam";

  printf("%s\n",strcat(str1,str2));	//applejam
  printf("%s\n",str1);			//applejam

  //strncat 예제
  char str3[20] = "apple";
  char str4[20] = "juicecup";

  printf("%s\n",strncat(str3,str4,5));	//applejuice
  printf("%s\n",str3);			//applejuice

  return 0;
}   

✔  두 문자열을 이어 붙여서 str1에 저장하기 때문에, 두 문자열을 이어 붙였을 때의 크기가 str1보다 작아야 한다.

 

 

 

5. 문자열 길이 확인 함수
   strlen(str)    문자열의 길이 반환 (\0를 제외한 길이)
#include <stdio.h>
#include <string.h>

int main(void)
{
  //strlen 예제
  char str1[] = "applejam";
  char str2[10] = "applejam";
  printf("%lu\n", strlen(str1));	//8
  printf("%lu\n", strlen(str2));	//8
  return 0;
}   

✔  배열의 크기를 지정하지 않고 초기화하면, 문자열의 길이만큼 자동으로 할당됨.

 

 

 

6. 문자열 분리 함수
   strtok(str, t)    str 내부에서 t를 찾아, t를 기준으로 문자열을 분리해 해당 포인터 반환
#include <stdio.h>
#include <string.h>

int main(void)
{
    char str[] = "Nice to Meet you";
    
    char *p1 = strtok(str," ");
    printf("%s\n",p1);		//Nice
    
    char *p2 = strtok(str," ");
    printf("%s\n",p2);    	//Nice
    return 0;
}   

✔  두 번째 인자로 받아온 토큰(공백 가능)을 기준으로 첫 번째 인자를 분리해 해당 포인터를 반환한다.

✔  첫번 인자의 문자열 전체를 원하는 토큰으로 분리해 출력하고 싶다면 아래 코드를 참고.

#include <stdio.h>
#include <string.h>

int main(void)
{
    char str[] = "Nice-to-Meet-you";
    
    char *p = strtok(str,"-");
    
    while(p!=0){
        printf("%s\n",p);
        p = strtok(NULL,"-");
    }
    
    printf("\n%s",str);
   
//출력값
//  	Nice
//	to
//	Meet
//	you
  
    return 0;
}   

✔  더 이상 분리할 문자열이 없는 경우 strtok() 함수는 null을 반환하므로, while문의 종료 시점을 null을 반환받았을 때로 설정.

✔  while문 내부에서 NULL을 넣어 strtok()를 사용하는 이유는 이전에 처리한 문자열의 다음 문자부터 확인하기 위함.

 

N i c e - t o - M e e t - Y o u \0

 

N i c e \0 t o - M e e t - Y o u \0

 

✔  strtok(str,"-") 을 사용하면, - 를 찾아 \0 으로 변경하기 때문에 위와 같은 변화가 생긴다.

✔  \0은 곧 문자열의 끝을 의미하므로, 이후에 아무리 strtok(str,"-") 을 사용한다 하더라도 더 이상 -를 찾지 못한다.

✔  즉, 한 번 분리를 한 후에 strtok(str,"-") 를 사용한다면 Nice만 계속 반환.

✔  그렇기 때문에 첫 번째 분리 이후에 while문 내부에서는 strtok()함수를 사용할 때, 첫번째 인자로 NULL을 넣어주어야 한다.

✔  NULL을 넣으면 직전에 실행했던 stroke함수에서 자른 만큼 다음 문자열로 이동해 토큰을 찾아 분리를 실행한다.

 

 

N i c e \0 t o - M e e t - Y o u \0

 

N i c e \0 t o \0 M e e t - Y o u \0

✔  첫 번째 실행에서 Nice를 분리했으니 두 번째 실행은 그 이후부터 토큰을 찾는다. (포인터 p에는 t의 주소가 저장)

 

 

N i c e \0 t o \0 M e e t - Y o u \0

 

N i c e \0 t o \0 M e e t \0 Y o u \0

✔  두번째 실행에서 to를 분리했으니 세 번째 실행은 그 이후부터 토큰을 찾는다. (포인터 p에는 M의 주소가 저장)

 

 

N i c e \0 t o \0 M e e t \0 Y o u \0

 

N i c e \0 t o \0 M e e t \0 Y o u \0

✔  세번째 실행에서 Meet을 분리했으니 네 번째 실행은 그 이후부터 토큰을 찾는다. (포인터 p에는 Y의 주소가 저장)

✔  이후 실행에서는 더 이상 토큰을 발견할 수 없으므로 strtok() 함수는 null 반환, 포인터 p에는 null이 저장되고 while문 종료. 

 


 

✔  한 번이라도 strtok() 함수를 사용하고 str을 출력한다면, 첫 번째 분리된 문자열 뒤에 바로 null이 저장되어 있으므로

✔  문자열의 끝으로 인식하기 때문에 더 이상 원래 저장되어 있었던 문자열 전체를 출력할 수 없다.

✔  이처럼 strtok 함수는 저장된 문자열의 내용을 변경하므로 사용 시 주의가 필요하다.

 

 

 

 

 

 

[참고] 한빛미디어-혼자 공부하는 C언어 유튜브 강의 / 엘리스 트랙-혼자 공부하는 C언어 / 길벗-C언어 코딩도장 / 위키백과

 

'BackEnd > C' 카테고리의 다른 글

[10일차] 제어문 복습  (0) 2021.02.20
[8일차] 포인터의 선언과 사용  (0) 2021.02.17
[7일차] 1. 문자열(char형 배열)  (0) 2021.02.16
[6일차] 2. 배열  (0) 2021.02.15
[6일차] 1. 재귀 호출 함수  (0) 2021.02.15
댓글
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
최근에 올라온 글
글 보관함
Total
Today
Yesterday