[C] sscanf 를 활용하여 파싱 코드를 좀 줄여보자구요~ Develop Tip

휴우, 파이썬을 사용하다가 간만에 C 소스를 보다보니 이십년만에 C 표준 라이브러리에 있는
sscanf 의 조금 더 고급스러운 기능을 사용해 보게 되네요.

일단, 아래의 sccanf 를 한번 보시면,

sscanf(buffer,"%50[^:/]://%2000[^/]/%s", protocol, host, path);

무언가 %d, %s 등과 달리 그 뒤에 나오는 것이 정규식과 유사 하기는 한데 뭔가를 겁이 나게 만드네요.
sccanf의 첫번째 패러미터는 실제 문자열을 담고 있는 포인터, 두번째가 포맷 문자열, 그 다음이 파싱해서
결과를 담을 변수들 인데요.

이것을 말로 한번 풀어 보겠습니다.
buffer에 있는 내용을 "%50[^:/]://%2000[^/]/%s" 로 파싱하여
protocol, host, path 등의 문자열에 넣어라 라는 내용 되겠습니다.

"%50[^:/]://%2000[^/]/%s" 내용 때문에 헷갈렸는데 man page를 보고도 이해가 안 되더라구요.
샘플을 짜서 돌려본 결과 쉽게 알게 되었습니다.

위에 것을 앞에서부터 설명하면,

%50[^:/]
것을 ':' 또는 '/' 문자를 제외한 문자열을 최대 50자까지 읽어서 protocol에 넣습니다.
://
"://" 문자열이 그 다음에 나타나야 하며 나타나지 않는다면 파싱에 실패합니다.
%2000[^/]
'/' 문자가 아닌 문자를 최대 2000자까지 읽어 host 에 넣습니다.
/%s
'/' 문자가 그 다음에 나와야 하면 안 나오면 파싱 실패이고, 그 다음 문자열을 끝까지 읽어 path에 넣습니다.


이제 이것을 이용하여, 샘플을 만들고,

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

main(int argc, char *argv[])
{
    char protocol[50];
    char host[2000];
    char path[2000];

    char buffer[1024];

    if (argc < 2) {
        fprintf(stderr, "usage: %s url\n", argv[0]);
        exit(1);
    }  

    strncpy(buffer, argv[1], sizeof(buffer));
    printf("buffer=<%s>\n", buffer);

    if(sscanf(buffer,"%50[^:/]://%2000[^/]/%s", protocol, host, path) == 3) {
        printf ("protocol=<%s>, host=<%s>, path=<%s>\n", protocol, host, path);
    }  
    else if (errno != 0) {
        perror("scanf");
    } else {
        fprintf(stderr, "No matching characters\n");
    }  
    return 0;
}

파일 이름이 ssc.c 라 하고,

$ gcc -o ssc -g ssc.c
와 같이 컴파일을 한 후,

$ ./ssc http://a.b.c:80/abc.htm
buffer=<http://a.b.c:80/abc.htm>
protocol=<http>, host=<a.b.c:80>, path=<abc.htm>

위와 같이 돌리면 쉽게 URL 파싱을 할 수 있음을 알 수 있습니다.

정규식은 아니지만 정규식을 적용하여 만들어 놓은 sscanf 를 좀 더
잘 활용할 수 있겠다는 생각이 드는군요~



덧글

  • 탓치 2011/04/07 14:06 # 삭제 답글

    도움이 많이 되었습니다.
    감사합니다:D
  • 지훈현서아빠 2011/04/07 14:37 #

    도움이 되셨다니 저의 기쁨입니다.
    다른 개발자 분들에게도 많이 오픈해주셔요~
  • 프로그래머 2013/01/31 15:19 # 삭제 답글

    대박이내요.. 감사합니다. 퍼갈꼐요. 출처 남깁니다.
  • 지훈현서아빠 2013/02/01 10:23 #

    도움이 되셨다니 저의 보람입니다~ ^^
  • 땡칠이 2019/05/14 10:23 # 삭제 답글

    찾던 내용인데 검색되어 실무 적용했습니다. 정말 감사합니다. 정말 감사합니다.
  • 지훈현서아빠 2019/05/14 16:08 #

    8년전 글인데 그렇게 도움이 되셨다니 저의 보람입니다~ ^^
댓글 입력 영역

구글애드텍스트