#keywords strcpy_s,strcpy,win32,windows,visual,studio,string,strncpy #title strcpy_s에 대해서 [wiki:Home 대문] / [wiki:CategoryProgramming 프로그래밍] / [wiki:strcpy_s strcpy_s에 대해서] ---- == [wiki:strcpy_s strcpy_s에 대해서] == * 작성자 조재혁([mailto:minzkn@minzkn.com]) * 고친과정 2011년 2월 12일 : 처음씀 [[TableOfContents]] === 개요 === 예전 VisualStudio 버젼에서는 정상적으로 strcpy 표준함수를 사용할수 있었으나 요즘에는 strcpy 를 사용하면 경고를 내보냅니다.[[br]] 물론 무시할수 있지만 무시하자니 경고누적으로 불안감이 증가하죠... 그래서 울며겨자먹기로 잘 설계된 코드마저도 MS의 강제적인 비표준안으로 코드를 수정해야 합니다.[[br]] 게다가 이렇게 수정하면 다른운영체제로 포팅할때도 다 수정해주어야 합니다.[[br]] 참 안좋은 상태만 만들어 가네요. 어쨌건 strcpy, strncpy를 strcpy_s로 바꾸는 작업을 할수밖에 없는데[[br]] 문제는 기존 코드를 아무생각없이 바꾸었다가는 낭패를 볼수 있습니다.[[br]] 그래서 정리합니다. strcpy_s와 strncpy는 같은 치환레벨이 아니라는 점을 말입니다. strncpy로 된 부분을 strcpy_s 로 치환하기 위해서는 크게 문제시 되는것은 두가지 입니다. 하나는 인자의 위치가 다르다는 점이고 또 다른 하나는 Source에 주어지는 문자열이 반드시 Null terminate되어야 한다는 점입니다.[[br]] Null terminate되지 않은 경우 일부 Window version에서는 예외가 발생되는데 또 어떤 버젼에서는 잘 돌아간다는 점입니다.[[br]] strcpy_s 와 strncpy함수는 동일한 목적의 함수가 아니라는 점을 인지해야 합니다. === strcpy_s === 1. Destination의 null terminate를 보장해준다. 1. Source 는 반드시 null terminate해주어야 한다. 그렇지 않으면 동작이 보장되지 않는다. 1. Size를 0 또는 그보다 작은크기대역으로 주면 error를 반환한다. 1. Destination과 Source의 메모리 영역이 겹치면 의도하지 않는 동작이 일어날수 있다. 1. Destination과 Source는 어느한쪽이라도 NULL이면 error를 반환한다. 1. multi-byte지원한다. 1. 구현은 다음과 같거나 유사한 행동을 할것이다. {{{#!enscript c errno_t strcpy_s(char *d, size_t dn, const char *s) { size_t cn; size_t c; if(d == NULL || s == NULL) { return(EINVAL); } if(dn <= ((size_t)0u)) { return(ERANGE); } --dn; cn = strlen(s /* s가 null terminate되지 않으면 동작이 보장되지 못한다. */); cn = (dn <= cn) ? dn : cn; for(c = 0;c < cn;c++) { d[c] = s[c]; } d[c] = '\0'; /* null terminate 보장 */ return 0; } }}} === strncpy === 1. Destination의 null terminate를 보장하지 않는다. 1. Source는 null terminate가 아닌 경우도 허용한다. 그렇지만 이 경우 Size보다 Source공간이 적은 경우 동작이 보장될수 없다. 1. Size가 0인 경우도 허용한다. 이 경우 아무 동작도 안한다. 1. Destination과 Source의 메모리 영역이 겹치면 의도하지 않는 동작이 일어날수 있다. 1. Destination과 Source는 어느한쪽이라도 NULL이면 동작을 보장할수 없다. 1. multi-byte 에 대한 고려는 정의하지 않는다. 1. 구현은 다음과 같거나 동등한 행동을 할것이다. {{{#!enscript c char *strncpy(char *d, const char *s, size_t dn) { size_t c; /* d 와 s중 하나라도 NULL인 경우 어떤일이 벌어질지 정의되지 않는다. */ for(c = 0;c < dn && s[c] != '\0';c++) { d[c] = s[c]; } for(;c < dn;c++) { d[c] = '\0'; } return d; } }}} === strlcpy === 1. Destination의 null terminate를 보장해준다. 1. Source 는 반드시 null terminate해주어야 한다. 그렇지 않으면 동작이 보장되지 않는다. 1. Destination과 Source의 메모리 영역이 겹치면 의도하지 않는 동작이 일어날수 있다. 1. multi-byte 에 대한 고려는 정의하지 않는다. 1. Source 문자열의 길이를 반환한다. * Destination 보다 반환 값(Source)이 큰 경우 복사된 문자열은 잘린 형태가 된다는 의미 1. 구현은 다음과 같거나 유사한 행동을 할것이다. (참고: [^https://man.freebsd.org/cgi/man.cgi?query=strlcpy&sektion=3]) {{{#!enscript c size_t strlcpy(char *d, const char *s, size_t dn) { size_t sl = strlen(s /* s가 null terminate되지 않으면 동작이 보장되지 못한다. */); size_t cn, c; if (dn-- > 0) { cn = (dn <= sl) ? dn : sl; for(c = 0;c < cn;c++) { d[c] = s[c]; } d[c] = '\0'; /* null terminate 보장 */ } return sl; } }}}