본문 바로가기
C/공부기록

[C기초 플러스] strcpy()함수 개념 및 기능 정리 (널 문자 복사)

by Just Do Barro 2021. 9. 19.

형식

strcpy(char * dest, char* source)

기능

  1. 두번째 전달인자(source)가 가리키는 문자열이 첫번째 전달인자(dest)가 가리키는 배열로 복사된다. 
  2. 대입문에서의 순서와 같이 오른쪽이 왼쪽에 대입.

리턴값

첫번째 전달인자의 값 (문자의 주소)

 

특징

  1. 첫번째 포인터(dest)는 그 문자열(source)을 저장할 수 있을 만큼 충분한 기억공간을 확보하고 있는, 배열과 같은 데이터 객체를 가리켜야한다. 
  2. 첫번째 전달인자가 반드시 배열의 시작을 가리킬 필요는 없다. 

예시

/* copy1.c--strcpy() 사용*/
#define _CRT_SECURE_NO_WARNINGS //strcpy()가 unsafe해서 빌드 오류 뜨지 않게 하기 목적
#include <stdio.h>
#include <string.h> /*strcpy() 선언*/
#define SIZE 40
#define LIM 5
char* s_gets(char* st, int n);
int main(void)
{
char qwords[LIM][SIZE]; //Q: 왜 2차원 배열로 선언? 1차원으로만 사용하던데
char temp[SIZE];
int i = 0;
printf("q로 시작하는 단어를 %d개 입력하시오: \n", LIM);
while (i < LIM && s_gets(temp, SIZE))
{
if (temp[0] != 'q') {
printf("%s: q로 시작하는 단어가 아닙니다.!\n", temp);
}
else {
strcpy(qwords[i], temp); //strcpy(dest, src)
i++; //q로 시작한 단어만 횟수 증가 적용
}
}
puts("받아들인 단어는 다음과 같습니다. : ");
for (i = 0; i < LIM; i++)
{
puts(qwords[i]); //q로 시작하는 단어 모두 출력 5개
}
return 0;
}
char* s_gets(char* st, int n)
{
char* ret_val; //리턴할 문자열의 주소
int i = 0; //변수 i는 0으로 초기화해야 다음 코드에서 변수로 사용 가능
ret_val = fgets(st, n, stdin); //키보드로 입력한 문자열 중 n-1개(공백 포함) 읽어서 st 배열에 저장.
if (ret_val) //0아닌 값: true. 키보드로부터 입력이 정상적으로 완료되면
{
while (st[i] != '\n' && st[i] != '\0') // NULL == \0 메모리 주소 0 (포인터 변수 초기화 할 떄 사용), \n == 출력후 줄바꿈
{
i++; //배열 인덱스 증가
}
if (st[i] == '\n') {
st[i] = '\0'; //줄바꿈 문자 -> 널 문자
}
else {
while (getchar() != '\n')
continue; // 입력한 문자열 중 \n를 만나면 그떄 while 문 벗어남.
}
return ret_val; //리턴할 문자열의 주소를 가리킴
}
}

 

실행결과

 

 

기능

strcpy()는 소스 문자열로부터 널 문자(\0, 문자열의 끝을 알려줌)를 복사한다.

/*copy2.c --strcpy() 사용*/
#define _CRT_SECURE_NO_WARNINGS // 'strcpy()' function is unsafe. To disable deprecation
#include <stdio.h>
#include <string.h>
#define WORDS "beast" //전처리 작업에서 처리. const는 컴파일 작업에서 처리
#define SIZE 40
int main(void)
{
const char* orig = WORDS; //(*변수) == 상수. 포인터가 가리키는 값 변경 불가. 주소변경 가능.
char copy[SIZE] = "Be the best that you can be";
char* ps;
puts(orig);
puts(copy);
ps = strcpy(copy + 7, orig); //strcpy(dest, src) dest의 문자 주소를 리턴
//copy +7 : 'best ' 자리에 'beast' (5자리 대체)
// strcpy()는 소스문자열로부터 널 문자(\0) 복사. 'beast\0' 을 copy+7 포함해서 대체.
//즉 Be the beast\0 (copy의 that의 t 자리에 \0가 오면서 문자열의 끝남을 표시. )
puts(copy);
puts(ps);
return 0;
}

참고

전처리(preprocessing)란?

소스코드를 컴파일하기 전에 미리 전처리문을 처리하는 것이다. #define, #include, #ifdef 같은 것을 말한다.

전처리문은 소스카 컴파일되기 전에 미리 처리되는 문장이다. 기존의 소스코드를 건드리지 않은 상태에서 부분적인 컴파일을 수행한다. 

#include <stdio.h>
#define PI 3.14
//원래 소스파일
int main(void)
{
int radius = 10;
area = radius * radius * PI;
return 0;
}
//전처리된 소스파일
int main(void)
{
int radius = 10;
area = radius * radius * 3.14;
return 0;
}
//전처리 후 컴파일하면 *obj 파일 생성 및 링킹되어 실행파일*exe이 생성된다.

 

원리

strcpy()함수는 null 문자도 복사한다.

문자열의 끝을 알려주는 널 문자 (\0)가 ps에 포함되어 저장되었기 때문에 ps를 출력한 결과에 'that you can be'가 나오지 않는다.

 

또한 copy + 7이 배열의 원소 중 몇 번째인지 알고자 할 때 0번째부터 시작함을 알고 세어야한다. 즉 copy +7 은 7번째가 아니라 8번째를 의미한다. 

실행결과

 

댓글