90. Secure 함수
1. 키워드
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