cCcode

C Language [핵심정리] - 20 본문

C Language Basic

C Language [핵심정리] - 20

cCcode 2021. 5. 30. 23:05

1. 문자열 복사하고 붙이기

문자열은 다른 배열이나 포인터로 복사할 수 있습니다. 복사할 때는 strcpy 함수를 사용하며, 함수명은 문자열 복사하기(string copy)에서 가져왔습니다. (<string.h>파일선언되어있습니다.)

strcpy 함수 사용
strcpy 함수 사용

strcpy 함수를 사용했더니 [error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead.] 라는 에러가 발생하네요. 간단히 설명하자면 strcpy 함수scanf 함수처럼 잠재적 위험 때문에 안전하지 못하니 strcpy_s 함수를 사용하라는 권고문입니다. 그전 scanf의 위험성은 딱히 언급하지 않았지만 이번에는 언급하고 넘어가겠습니다. strcpy 함수복사될 메모리의 크기보다 원본 문자열의 크기가 더 클 경우 버그가 발생합니다. 그래서 저희는 strcpy_s 함수를 사용할 때는 복사될 메모리의 크기를 두번 째 인자에 반드시 명시해줘야 합니다.

strcpy_s 함수의 사용법
strcpy_s 함수 사용 예제 - 1
strcpy_s 함수 사용 예제 - 2
결과

strcpy 함수일 경우에는 잠재적 에러인 상태가 되지만, strcpy_s 함수를 사용할 경우 이처럼 디버그 에러창을 표시함으로 어떤 코드에서 에러발생한 것인지 좀더 간편하게 알 수 있습니다. 여기서 에러가 난 이유는 제가 buffer(빈 공간) 즉, 두번 째 인자로 주어진 원본 문자열크기를 잘못 주었기 때문입니다. ex) Basic 일때는 B(1) a(2) s(3) i(4) c(5) 이므로 5의 크기를 주어야 한다 착각할 수 있지만 literal 값일지라도 널문자를 포함해야 하기에 총 6이라는 크기명시해줘야 합니다.

크기 수정
결과

이처럼 strcpy_s 함수두번 째 인자 값을 모두 수정하면 문제 없이 값이 출력된다는 것을 알 수 있습니다.

 

그래서 우리는 여기서 "각 포인터는 포인터끼리 문자열 복사가 가능하지않을까?" 하는 추측을 할 수 있는데, 안타깝게 그 추측은 절반만 맞았다고 할 수 있겠네요. 먼저 배열끼리의 문자열 복사를 보시죠. 

배열간의 문자열 복사
결과

당연히 배열끼리의 복사는 가능합니다. 그럼 이제 포인터끼리의 문자열 복사를 보시죠.

포인터간의 문자열 복사
결과

결과를 보시면 아무것도 출력되지 않으며, 코드가 0이 아닌 값을 반환해 비정상적인 종료임을 알려주고 있습니다. 

return 함수 설명 

이를 통해 저희는 포인터의 메모리읽기 메모리문자열 복사(수정)이 되지않음을 다시 한번 알 수 있었습니다.

그래도 포인터를 사용하고 싶다면

#include <stdlib.h>
//	+
char *s2 = malloc(sizeof(char) * 16);

이처럼 동적 메모리 할당을 이용해 배열처럼 사용하면 됩니다. 

free(s2);

메모리를 해제해주는 것도 잊으시면 안되고요.

 

문자열을 붙일 때는 strcat 함수사용하며 함수명문자열을 연결시키다(string concatenate)에서 가져왔습니다. (<string.h>파일에 선언되어 있습니다.)

strcat 함수 사용

아,, 일단 여러분들에게 설명드렸는지 기억이 나지않는데 값을 선언 동시에 할당할 때 해당 문자열보다 공간이 커서 공간이 남는다면 그 공간(문자열로 채워지지않은)은 널 문자로 채워집니다. 

빈 공간 널문자
결과

결과를 보시면 할당된 문자열보다 큰 공간선언해서 남은 공간널문자로 채워짐을 보실 수 있습니다. 간단하죠?

 

일단 배열 간의 문자열 연결을 보시죠.

배열 간의 문자열 연결
결과

여기서 최종 문자열의 크기는 널문자까지 포함해서 생각해야 합니다.

이제 포인터 간의 문자열 연결입니다.

포인터 간의 문자열 연결
디버그 결과 - 1
디버그 결과 - 2

왜 이러한 결과가 발생했고 이유는 제가 계속 언급했기에 무엇인지 설명하지 않아도 아실겁니다. 그리고 strcat 함수 또한 지금까지 배운 문자열을 다룬 함수들과 같이 보안상의 문제로 strcat_s 함수사용을 권장하고 있습니다. strcat_s 함수는 두 번째 인자에 복사를 받을(붙여지는) 변수의 크기명시해야 합니다.

수정
결과

 

그럼 이해가 되셨는지 확인하기 위해 아래 문제를 풀어보시죠.

Q. 배열에는 "I love C"라는 문자열을 할당하고 포인터에는 "But little hard."라는 문자열을 할당합니다. 그리고 배열만 출력하여 "I love C But little hard."라는 문장을 출력하세요.(다만, 배열과 포인터는 선언과 동시에 할당해선 안되며, 두 문자열 사이에 공백을 두고 출력해야 합니다.)

 

A.

더보기
모범 답
결과

 

'C Language Basic' 카테고리의 다른 글

C Language [핵심정리] - 22  (0) 2021.06.02
C Language [핵심정리] - 21  (0) 2021.06.01
C Language [핵심정리] - 19 + ∂  (1) 2021.05.29
C Language [핵심정리] - 19  (0) 2021.05.28
C Language [핵심정리] - 18  (2) 2021.05.27
Comments