Skip to content

90. Secure 함수


1. 키워드

  • Secure 함수


2. Secure 함수 사용하기

  • C의 기본 함수들은 입력 값의 길이나 버퍼의 크기(문자 개수)를 설정할 수 없어 보안에 취약한 경우가 많다.
  • 따라서 Visual Studio에서는 보안이 향상된 함수를 제공하며 기본 함수에 _s가 붙어있다.


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

int main()
{
    int num1;
    char s1[20];
    // 문자열은 버퍼의 크기를 넣어줌
    scanf_s("%d %s", &num1, s1, _countof(s1));
    printf("%d %s\n", num1, s1);

    wchar_t ws1[20];
    // wchar_t 문자열은 문자열의 개수를 넣어줌
    wscanf_s(L"%d %s", &num1, ws1, _countof(ws1));
    wprintf(L"%d %s\n", num1, ws1);

    sprintf_s(s1, _countof(s1), "%s", "Hello, world!");
    printf("%s\n", s1);

    swprintf_s(ws1, _countof(ws1), L"%s", L"Hello, world!");
    wprintf(L"%s\n", ws1);

    strcat_s(s1, _countof(s1), "123");
    printf("%s\n", s1);

    wcscat_s(ws1, _countof(ws1), L"123");
    wprintf(L"%s\n", ws1);

    char s2[20];
    wchar_t ws2[20];

    strcpy_s(s2, _countof(s2), s1);
    printf("%s\n", s2);

    wcscpy_s(ws2, _countof(ws2), ws1);
    wprintf(L"%s\n", ws2);

    char s3[20] = "The Little Prince";
    char *ptr1;
    char *next1;

    ptr1 = strtok_s(s3, " ", &next1); // next1에는 다음번에 자를 문자열의 포인터가 들어감
    while (ptr1 != NULL)
    {
        printf("%s\n", ptr1);
        ptr1 = strtok_s(NULL, " ", &next1);
    }

    wchar_t ws3[20] = L"The Little Prince";
    wchar_t *ptr2;
    wchar_t *next2;

    ptr2 = wcstok_s(ws3, L" ", &next2); // next2에는 다음번에 자를 문자열의 포인터가 들어감
    while (ptr2 != NULL)
    {
        wprintf(L"%s\n", ptr2);
        ptr2 = wcstok_s(NULL, L" ", &next2);
    }

    return 0;
}

// 10 Hello  (입력)
// 10 Hello
// 20 world  (입력)
// 20 world
// Hello, world!
// Hello, world!
// Hello, world!123
// Hello, world!123
// Hello, world!123
// Hello, world!123
// The
// Little
// Prince
// The
// Little
// Prince


  • 먼저 scanf_s, wscanf_s 함수는 문자열을 입력받을 때 문자열 버퍼의 문자 개수를 지정해야 한다.
  • 숫자나 문자일 때는 문자 개수를 지정하지 않아도 된다.


scanf_s("%d %s", &num1, s1, _countof(s1));
wscanf_s(L"%d %s", &num1, ws1, _countof(ws1));


  • Visual Studio에서는 문자열 버퍼의 문자 개수를 구하는 _countof 매크로를 제공하는데 sizeof(s1) / sizeof(char)와 또는 sizeof(ws1) / sizeof(wchar_t)와 결과가 같다.


#define _countof __crt_countof
#define __crt_countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))


  • 나머지 _s가 붙은 함수들도 문자열을 생성하거나 복사할 때 목적지 포인터의 문자 개수를 지정해서 사용하면 된다.


  • 다음은 파일 처리 함수이다.


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

int main()
{
    FILE *fp;
    fopen_s(&fp, "hello.txt", "w+"); // 파일 포인터의 주소를 넣음

    fputs("Hello 100", fp);

    rewind(fp);

    char buffer[100] = {
        0,
    };
    int num1;

    fscanf_s(fp, "%s %d", buffer, _countof(buffer), &num1);
    printf("%s %d\n", buffer, num1);

    rewind(fp);
    memset(buffer, 0, sizeof(buffer));

    // 버퍼 크기, 읽기 크기, 읽기 횟수를 지정
    fread_s(buffer, sizeof(buffer), 20, 5, fp);
    printf("%s\n", buffer);

    rewind(fp);
    memset(buffer, 0, sizeof(buffer));

    // 버퍼 크기와 읽기 크기를 같게. 읽기 크기는 1로 지정
    fread_s(buffer, sizeof(buffer), sizeof(buffer), 1, fp);
    printf("%s\n", buffer);

    fclose(fp);

    return 0;
}

// Hello 100
// Hello 100
// Hello 100


  • fread_s 함수는 fread_s(buffer, sizeof(buffer), 20, 5, fp);와 같이 총 버퍼 크기 sizeof(buffer)를 먼저 지정해 주고 읽기 크기, 읽기 횟수를 지정하면 된다.

References