2015년 8월 26일 수요일

C 언어 - 문자열

문자열을 잘 처리할 줄 알게 되면 프로그래밍에 자신감이 붙게 된다.

문자열 처리를 위해서는 지금까지 이야기한 초기화와 배열 처리에 대한 이해가 있어야 한다.

문자열 초기화


고정 문자열

const char * name = "Hello";

"Hello" 는 자동으로 const char 배열로 선언된다.
const char * 는 문자열을 변형할 수 없다는 의미다.

배열 크기


문자열은 끝을 표시하기 위해 '\0' 이 추가로 붙는다.
H e l l o \0
문자열 Hello 는 5문자 이지만 자동으로 6 바이트 배열이 선언된다.

변경 가능 문자열


char name[128];
strcpy(name, "Steve");
printf("Name: %s\n", name);
strcpy(name, "Bob");
printf("Name: %s\n", name);

실행:
Name: Steve
Name: Bob

strcpy 분석


char * strcpy(char * destination, const char * source);
http://www.cplusplus.com/reference/cstring/strcpy/



  • char * destination : 복사 대상
  • const char * source : 복사할 문자열 (const char * 로 선언함으로써 strcpy 내부에서 source 는 변경되지 않음을 보장 받을 수 있다)

strcpy 소스
http://www.opensource.apple.com/source/Libc/Libc-167/gen.subproj/ppc.subproj/strcpy.c

char * strcpy(char *s1, const char *s2)
{
    char *s = s1;
    while ((*s++ = *s2++) != 0);
    return (s1);
}


  • (*s++ = *s2++) != 0 : 0, 즉 문자열 끝을 알리는 0 을 만날 때 까지 destination 에 한 문자씩 대입

결론적으로 source 는 반드시 0 으로 끝나야 한다.


strncpy

str n cpy

destination 이 source 보다 배열 크기가 작을 경우 어떻게 처리해야 할까?
destination 크기 까지만 복사하고 나머지는 버리는게 대부분 맞다.

char * strncpy ( char * destination, const char * source, size_t num );


  • destination : 복사 대상
  • source : 복사할 문자열
  • num : 최대 복사 크기


num 에는 보통 복사 대상의 크기 - 1를 입력한다.
- 1 은 마지막 0 을 위해 남겨둔다.

예)

char buffer[10] = {0,};
strncpy(buffer, "Donovan Harrison", sizeof(buffer) - 1);
printf("%s\n", buffer);


실행:
Donovan H

안전한 함수


n 자가 들어간 함수들은 버퍼 크기 안에서만 처리하게 되기 때문에 안전한 함수들이다.
안전한 함수들을 사용하자.


  • strncpy() : 문자열 복사
  • strnlen() : 문자열 길이
  • strncmp() : 문자열 비교
  • strncat() : 문자열 덧붙이기
  • snprintf() : 문자열 만들기


문자열 처리 표준 API 예


#include <stdio.h>
#include <string.h>
static void s_strncpy() {
    char buffer[10] = {0,};
    strncpy(buffer, "Donovan Harrison", sizeof(buffer) - 1);
    printf("%s\n", buffer);
}
static void s_strnlen() {
    char buffer[10] = {0,};
    size_t len;
    len = strnlen(buffer, sizeof(buffer));
    printf("buffer: \"%s\", length: %lu\n", buffer, len);
    strncpy(buffer, "hello", sizeof(buffer) - 1);
    len = strnlen(buffer, sizeof(buffer));
    printf("buffer: \"%s\", length: %lu\n", buffer, len);
}
static void s_strncmp() {
    char a[10] = {0,};
    char b[10] = {0,};
    strncpy(a, "abc", sizeof(a) - 1);
    strncpy(b, "abc", sizeof(b) - 1);
    printf("%s == %s : %d\n", a, b, strncmp(a, b, sizeof(a)));
    strncpy(a, "abc", sizeof(a) - 1);
    strncpy(b, "cba", sizeof(b) - 1);
    printf("%s == %s : %d\n", a, b, strncmp(a, b, sizeof(a)));
    strncpy(a, "abc", sizeof(a) - 1);
    strncpy(b, "a", sizeof(b) - 1);
    printf("%s == %s : %d\n", a, b, strncmp(a, b, sizeof(a)));
    strncpy(a, "a", sizeof(a) - 1);
    strncpy(b, "abc", sizeof(b) - 1);
    printf("%s == %s : %d\n", a, b, strncmp(a, b, sizeof(a)));
}
static void s_strncat() {
    char buffer[128] = {0,};
    strncpy(buffer, "Hello ", sizeof(buffer) - 1);
    strncat(buffer, "Steve", sizeof(buffer) - 1);
    printf("%s\n", buffer);
}
static void s_snprintf() {
    char buffer[128] = {0,};
    snprintf(buffer, sizeof(buffer), "Your name is %s and age is %d\n", "Bob", 24);
    printf("%s\n", buffer);
}
int main(int argc, char *args[]) {
    printf(" == strncpy == \n");
    s_strncpy();
    printf(" == strnlen == \n");
    s_strnlen();
    printf(" == strncmp == \n");
    s_strncmp();
    printf(" == strncat == \n");
    s_strncat();
    printf(" == snprintf == \n");
    s_snprintf();
    return 0;
}

실행:
 == strncpy ==
Donovan H
 == strnlen ==
buffer: "", length: 0
buffer: "hello", length: 5
 == strncmp ==
abc == abc : 0
abc == cba : -2
abc == a : 98
a == abc : -98
 == strncat ==
Hello Steve
 == snprintf ==
Your name is Bob and age is 24



댓글 없음:

댓글 쓰기