C 언어 에서 sscanf()함수 의 문자열 포맷 방법

소개 하 다.
     sscanf()는 C 언어 표준 라 이브 러 리 함수 로 지정 한 문자열 에서 지정 한 형식 과 일치 하 는 데 이 터 를 읽 을 수 있 습 니 다.함수 원형 성명 은 stdio.h 헤더 파일 에 있 습 니 다:

int sscanf(const char *str, const char *format, ...);
     이 함 수 는 매개 변수 format(포맷 문자열)에 따라 매개 변수 str 가 가리 키 는 문자열 을 변환 하고 변 환 된 결 과 는 대응 하 는 가 변 매개 변수 에 저 장 됩 니 다.그 반환 값 은 지정 한 형식 변환 문자 에 따라 성공 적 으로 읽 고 값 을 부여 하 는 가 변 매개 변수 수 입 니 다.첫 번 째 변환 에 성공 하거나 오류 가 발생 하기 전에 입력 이 끝 났 을 경우(예 를 들 어 str 가 빈 문자열 인 경우)EOF 로 돌아 갑 니 다.읽 기 오류 가 발생 했 을 때 도 EOF 를 되 돌려 주 고 오류 코드 errno 를 설정 합 니 다(예 를 들 어 format 이 빈 포인터 일 때 EOF 를 되 돌려 주 고 errno 를 EINVAL 로 설정 합 니 다).이 함수 의 반환 값 과 지정 한 가 변 매개 변수 수 를 비교 하여 형식 변환 이 성 공 했 는 지 판단 할 수 있 음 을 알 수 있 습 니 다.
     format 은 하나 이상 의 {%[*] [width] [{h | l | L}]type | ' ' | '\t' | '
' | % }
형식 변환 부호 가 될 수 있다.집합 중 {a|b|c} 은 형식 부호 a,b,c 가 하 나 를 선택 하 는 것 을 나타 낸다.중 괄호 로 묶 은 형식 부 호 를 선택 할 수 있 습 니 다.type 과 필수 입 니 다.모든 형식 부 호 는%로 시작 해 야 합 니 다. 
 다음은 각 형식 문자 의 의 미 를 간략하게 설명 한다.
     1)할당 억제 문자'*'는 다음 변환 문자 의 지시 에 따라 입력 을 읽 지만 할당 하지 않 는 것 을 버 립 니 다('건 너 뛰 기').억제 부 호 는 해당 하 는 포인터 가 변 매개 변수 가 필요 하지 않 습 니 다.이 변환 은 함수 가 되 돌아 오 는 성공 할당 횟수 。%*[width] [{h | l | L}]type 에 포함 되 지 않 습 니 다.이 조건 을 만족 시 키 는 문자 가 걸 러 지고 목표 매개 변수 에 할당 되 지 않 습 니 다.
     2)width 은 최대 읽 기 폭 을 나타 낸다.이 값 을 초과 하거나 일치 하지 않 는 문 자 를 만 났 을 때 읽 기 를 중단 합 니 다.대부분의 변환 은 초기 공백 문 자 를 버 립 니 다.버 려 진 문자 와 변환 결과 에 추 가 된 빈 끝 문자('\0')는 최대 읽 기 폭 을 계산 하지 않 습 니 다.
     3){h | l | L} 은 유형 장식 부호 이다.h.입력 한 숫자 수 치 는 short int 또는 unsigned short int 형식 으로 저장 합 니 다.hh 지시 입력 은 signed char 또는 unsigned char 형식 으로 저 장 됩 니 다.l(소문 자 L)지시 입력 은 long int,unsigned long int 또는 double 형식 으로 저장 되 며,%c 또는%s 와 결합 하면 입력 을 넓 은 문자 나 넓 은 문자열 로 저장 합 니 다.ll 은 L 과 같다.L 지시 입력 은 long long 형식 으로 저 장 됩 니 다.
     4)type 은%s,%d 와 같은 유형 변환 부호 이다.
그 밖 에 두 가지 특수 한 형식 문자 도 있다.
     1)[]:문자 집합.[]지정 한 문자 집합 이 비 어 있 는 문자 시퀀스 와 일치 하 는 것 을 표시 합 니 다.^거르다이 동작 은 공백 문자(빈 칸,탭 또는 줄 바 꿈 문자)를 건 너 뛰 지 않 기 때문에 대상 문자열 이 공백 문자 로 구분 되 지 않 을 때 사용 할 수 있 습 니 다.[]하나 이상 의 비^문자(연결 문자'-'포함)가 있 고 순서 가 없습니다.%[a-z]는 a 에서 z 사이 의 임의의 문자 와 일치 하고%[AB-]는 a,B,-중의 임의의 문자 와 일치 합 니 다.%[^a]는 a 가 아 닌 임의의 문자 와 일치 합 니 다.즉,첫 번 째 a 이전의(a 가 아 닌)모든 문 자 를 가 져 옵 니 다.^여러 조건 에 작용 할 수 있 습 니 다.예 를 들 어^a-z=표시^a-z 및^=(소문 자 도 아니 고 등호 도 아 닙 니 다).빈 문자 집합%[]과%[^]는 예측 할 수 없 는 결 과 를 가 져 옵 니 다.
     []를 사용 할 때 입력 한 인 자 는 저장 공간 이 충분 한 char、signed char 또는 unsigned char 배열 이 어야 합 니 다.[]변환 부호 이기 때문에%[]후 s 가 없습니다.
   %[^]의 의미 와 용법 은 정규 표현 식 과 같 기 때문에 sscanf 함 수 는 어느 정도 간단 한 정규 표현 식 기능 을 제공 합 니 다.
     2)n:이 값(할당 되 지 않 음)의 등가 문자 수 를 읽 었 습 니 다.이 수 는 int 형식 으로 저장 해 야 합 니 다.예 를 들 어'10,22'가'%d%*[^0-9]%n'형식 으로 전환 되면%n 에 대응 하 는 매개 변수 값 은 3(비록','할당 에 참여 하지 않 음)입 니 다.
     'n'은'*'로 억제 할 수 있 음 에 도 불구 하고 변환 부호 가 아 닙 니 다.C 표준 에 따 르 면%n 명령 을 실행 하면 함수 가 되 돌아 오 는 할당 횟수 를 증가 하지 않 습 니 다.그러나 그 교정 표 의 묘사 와 모순.%n 이 반환 값 에 미 치 는 영향 을 가정 하지 않 는 것 을 권장 합 니 다.
 
다음 표 는 sscanf 함수 에서 흔히 볼 수 있 는 포맷 방법 을 열거 합 니 다.

그 밖 에 다음 과 같은 몇 가지 용법 도 있다.
    【예 1]문자열 한 줄 읽 기
     문자열 에 공백 문자 가 있 을 수 있 기 때문에%s 를 직접 사용 할 수 없습니다.한편,gets 함수 에 넘 치 는 위험 이 존재 하 므 로 추천 하지 않 습 니 다.이 때 sscanf 함 수 를 사용 할 수 있 습 니 다.포맷 문자열 은'%[^]%*c'로 설정 합 니 다.%*c.다음 줄 을 다시 읽 을 수 있 도록 줄 바 꿈 자 를 건 너 뛰 는 데 사용 합 니 다.
    【예 2]"Name=Yuan"의"Name"추출
     줄 의 맨 위 에 공백 문자 가 있 으 면 "%*[ \t]%[^= \t]" 형식 문자열 을 사용 할 수 있 습 니 다.
     줄 의 맨 위 에 공백 문자 가 있 는 지 확인 되 지 않 으 면 먼저 공백 문 자 를 건 너 뛸 수 있 습 니 다:

char szName[] = "Name  =  Yuan";
char szResBuf[32] = {0};
sscanf(szName+strspn(szName," \t"), "%[^= \t]", szResBuf);
    【예 3]URL 분해
     일반 실현 은 다음 과 같다.

/*****************************************************************************
 *     :OaSplitPwFarEndIpInfo
 *     :   IP       IP      
 *     :  IP     'udp://192.168.100.221:5000'
*****************************************************************************/
static FUNC_STATUS OaSplitPwFarEndIpInfo(INT8U *pucFarEndIpInfo, INT32U *dwDstUdpPort, INT8U *pucDstIpAddr)
{
  FUNC_STATUS retCode = S_OK;
  INT8U strUdpHead[] = "udp://";
  INT8U ucUdpUrlLen = strlen(strUdpHead);
  INT8U ucIndex = 0;

  CHECK_TRIPLE_POINTER(pucFarEndIpInfo, dwDstUdpPort, pucDstIpAddr, S_NULL_POINTER);

  if(strncasecmp(pucFarEndIpInfo, strUdpHead, ucUdpUrlLen) != 0)
  {
    OmciLog(LOG_CES,"[%s]Cannot Parse FarEndIpInfo(%s)!
\r", __FUNCTION__, pucFarEndIpInfo); return S_ERROR; } INT8U ucMaxUrlLen = ucUdpUrlLen + STR_IPV4_MAX_LEN; // (infinite loop) for(ucIndex = 0; (pucFarEndIpInfo[ucUdpUrlLen] != ':') && (ucUdpUrlLen < ucMaxUrlLen); ucIndex++) { pucDstIpAddr[ucIndex] = pucFarEndIpInfo[ucUdpUrlLen++]; } pucDstIpAddr[ucIndex] = '\0'; *dwDstUdpPort = strtoul(&pucFarEndIpInfo[ucUdpUrlLen+1], NULL, 10); return retCode; }
     sscanf 포맷 을 사용 하면 더욱 간단 합 니 다:

char szUrl[] = "udp://192.168.100.221:5000";
char szProt[4] = {0}, szIp[32] = {0};
unsigned int dwPort = 0;
sscanf(szUrl, "%[^://]%*c%*c%*c%[^:]%*c%d", szProt, szIp, &dwPort);
printf("szProt=%s, szIp=%s, dwPort=%d
", szProt, szIp, dwPort);
    【예 4]숫자 추출

char szDig[]="10,22m,Z86,,880;555:666."; 
int dwIdx = 0, dwVal = 0, dwSize = 0;
while(1 == sscanf(szDig+dwIdx, "%d%*[^0-9]%n", &dwVal, &dwSize))
{
  dwIdx += dwSize;
  printf("dwIdx=%d, dwSize=%d, dwVal=%d
", dwIdx, dwSize, dwVal); }
     위 에서 약간 개 조 를 실현 하면 특정한 문자 로 구 분 된 숫자 문자열 을 처리 할 수 있 습 니 다.
총결산 
     종합 적 으로 간단 한 문자열 분석 은 sscanf 함수 로 처리 하 는 것 이 간결 합 니 다.문자열 이 복잡 하면 정규 표현 식 라 이브 러 리 를 빌 릴 수 있 습 니 다.sscanf 포맷 의 목적 은'캡 처'이 고 정규 표현 식 의 목적 은'일치'이 며 완전히 같 을 수 없습니다.
     이상 은 본 논문 의 모든 내용 이 바 뀌 었 습 니 다.여러분 의 학습 에 도움 이 되 기 를 바 랍 니 다.궁금 하 시 면 댓 글 을 달 아 토론 하 시기 바 랍 니 다.

좋은 웹페이지 즐겨찾기