[C++] sscanf_s, _stscanf_s

[C++] sscanf_s, _stscanf_s

함수를 까먹어서 기록하기 위한 글입니다.
어떤 문자열이 있을 때 정해진 포맷이 있다면 그 포맷에서 데이터를 추출하는 경우가 있습니다.

C++인 경우엔 regex를 사용하면 정확한 문자열 검증이 가능하지만, 간단하게 사용할 수 있는 sscanf_s 함수도 제공합니다.(MFC에서는 _stscanf_s사용)

int sscanf_s(
   const char *buffer,
   const char *format [,
   argument ] ...
);
int _sscanf_s_l(
   const char *buffer,
   const char *format,
   _locale_t locale [,
   argument ] ...
);
int swscanf_s(
   const wchar_t *buffer,
   const wchar_t *format [,
   argument ] ...
);
int _swscanf_s_l(
   const wchar_t *buffer,
   const wchar_t *format,
   _locale_t locale [,
   argument ] ...
);

함수가 성공적으로 수행되면 할당된 필드 수를 반환합니다. 

예를 들어 IP를 문자열로 받고 입력된 값을 검증하는 함수를 만든다고 하면 아래 규칙을 적용해야 합니다.

  • 문자열 길이는 최소 7글자에서 최대 15글자
  • 4개의 정수가 들어가고, 각 정수는 점(.)으로 구분
  • 각 정수는 0~255 값 입력 가능

IP를 검증하는 코드는 아래와 같습니다.

#include <iostream>
using namespace std;

int InvalidIP(char* pcIP)
{
	cout << "IP Check: " << pcIP << endl;
	int aiIP[4] = {0,};
	char acIP[10] = {'\0',};
	int iCount = sscanf_s(pcIP, "%d.%d.%d.%d", &aiIP[0], &aiIP[1], &aiIP[2], &aiIP[3]);
	if (iCount != 4)
	{
		cout << "Fail - Invalid ip format" << endl;
		return -1;
	}

	for (int i = 0; i < 4; i++)
	{
		if (aiIP[i] < 0 || 255 < aiIP[i])
		{
			cout << "Fail - Invalid Value(index: " << i << ", value: " << aiIP[i] << ")" << endl;
			return -2;
		}
	}

	cout << "valid IP!" << endl;
	return 0;
}

int main ()
{
	char acIP1[12] = "192.168.0.1"; // 제대로 된 IP
	InvalidIP(acIP1);
	cout << endl;

	char acIP2[12] = "192.1680.1"; // 점(.)이 3개임
	InvalidIP(acIP2);
	cout << endl;

	char acIP3[12] = "192.256.0.1"; // 255 이상 숫자를 씀
	InvalidIP(acIP3);
	cout << endl;

	return 0;
}

정확한 검증을 위해서는 코드가 더 보완되어야 하지만 sscanf_s 사용 예제만 알아보는 글이니 여기까지 하겠습니다.