sscanf() 질문...

alkfjalfja의 이미지

아래와 같은 c code가 있는데...

sprintf의 %%%u[^\x01-\x1f] 부분과

sscanf 함수 내의 사용 방법에 대한 이해가 잘 되지 않습니다.

도움 좀 부탁 드리겠습니다.

====================================================
u8 include[513];
u8 fmt[20];

................

sprintf((char*)fmt, "%%%u[^\x01-\x1f]", 512);
sscanf((char*)tmp + 8,(char*)fmt, (char*)include);
====================================================

라스코니의 이미지

scanf 에 regular expression 을 사용할 수 있습니다.
자세한 것은 regular expression 메뉴얼을 참고하세요.

Anti-Lock의 이미지

[a-b] 나 [^a-b] 같은 형태로 제한적인 형식만 취할수 있는것 아닌가요?
regular expression 메뉴얼을 참고하는것은 scanf 함수하고는 별로 연관이 없을 것 같습니다.

http://www.cplusplus.com/reference/cstdio/scanf/

익명 사용자의 이미지

1. sprintf((char*)fmt, "%%%u[^\x01-\x1f]", 512);

%% : % (printf의 escape sequence)
%u : unsigned int의 10진 출력
[^ : 그냥 문자 그대로 [^
\x01 : C string literal의 escape sequence 로써 character code (아마도 ASCII) 1
- : 앞 문자부터 뒷 문자까지
\x1f : 앞서와 같음. 이번엔 character code 31

결국 fmt에 들어갈 문자열은 이렇겠네요. "%512[^\x01-\x1f]"
왜 이렇게 하드코딩 하지 않고 512를 별도로 집어넣는지는 잘 모르겠네요. 뭐 예컨대 512가 매직넘버라서 별도의 상수로 정의되었다던가 등의 이유가 있겠죠?
아무튼.

2. sscanf((char*)tmp + 8,"%512[^\x01-\x1f]", (char*)include);

tmp의 앞 8byte는 안 쓰는 모양이군요. 뭐 태그가 있다던가, 이유가 있겠죠.
% : format specifier 시작
512 : 최대 512문자. 마침 include 크기도 딱 513byte(512byte + NULL)네요.
[^ : Negated scanset 시작.
\x01-\x1f : character code 1부터 31까지. ASCII 코드표를 참고해 보시면, 이 부분이 딱 컨트롤 코드들이 위치한 영역입니다.
] : Negated scanset 끝

즉 sscanf는 tmp의 8바이트 오프셋부터 읽기 시작하여, ASCII code 1~31에 위치한 컨트롤 코드들을 발견할 때까지, 혹은 512byte를 읽었을 때까지 include에 써 나갑니다.

익명 사용자의 이미지

[^\x01-\x1f]는 ASCII code 1 ~ 31이 "아닌" 문자들을 최대한 많이 읽으려 하기 때문에, ASCII 1 ~ 31인 문자를 발견하면 거기서 바로 멈추는 겁니다.
물론 그런 문자를 발견하지 않았더라도 최대값인 512byte만큼 읽으면 멈춥니다.

Anti-Lock의 이미지

좋은 설명 감사합니다.
그런데, 문자열을 읽는다는 뜻인 %s 가 없네요..?
본래 코드에서 빠진듯 합니다.

익명 사용자의 이미지

http://www.cplusplus.com/reference/cstdio/scanf/

제시해주셨던 페이지 직접 확인해보세요.

%s에서 s(String of characters)가 specifier이듯 Negated scanset([^..])도 specifier이기 때문에 %[^abc] 같은 것도 유효한 format specifier입니다.
거기에 width를 지정한 %512[^abc]도 유효한 format specifier이고요.

Anti-Lock의 이미지

감사합니다.

예사로 봤었는데, s 가 없어도 되는군요...
16년만에 알게 되었습니다.ㅠㅠ

그러고 보니 printf 소스는 본적 있지만,
scanf 소스는 본적이 없는 것 같네요..
한번 봤다면 (낮은 확률로) 알았을 텐데요..

한편...
이렇게 친절하게 설명도 해주시고 좋은데 왜 익명으로 올라셨나요?
저는 CAPTCHA 입력하기가 더 어렵던데요ㅎㅎ

익명 사용자의 이미지

없어도 되는 게 아니라 사실 쓸데없이 있으면 안됩니다. -_-;
scanf의 format string에 공백이 아니고 format specifier가 아닌 일반 문자가 들어가면, 입력의 그 지점에서 반드시 그 문자가 있지 않으면 scanf가 실패하거든요.
(위 링크에서 "Non-whitespace character, except format specifier" 아이템을 읽어보세요)

즉 "%[^abc]s" 같은 식으로 써버리면 'a', 'b', 'c'가 아닌 문자들을 계속 읽다가 'a', 'b', 'c' 중 하나가 들어오면 Negate scanset이 실패하고, 그 문자는 당연히 's'도 아닐 거기 때문에 scanf가 그 지점에서 멈춰 버립니다.
물론 이 예에서는 s가 뒤에 있으나 없으나 원하는대로 동작하죠. 질문자님의 원래 코드도 그렇고요. 그래서 일단 "없어도 됩니다"라고 말씀드린 겁니다.
scanf의 format string에 엉뚱한 문자가 들어가서(혹은 필요한 문자가 없어서) 생기는 문제는 주로 scanf 하나에 format specifier 여럿 넣어서 사용할 때 자주 발생합니다.
예시는 생략할게요. 혹시 숫자 하나 문자 하나 입력받으려고 "%d%c" 썼다가 낭패본 기억 없으신 분?

그건 그렇고.
근래 KLDP 프로그래밍 Q&A 보드에서 익명으로 활동중인데 그럴 이유라면 나름 여럿 있습니다.

1. 어차피 닉네임 걸고 쓴다 해도 그건 뭐 실명인가요. 원한다면 아무 닉네임이나 써도 되는 걸.
KLDP의 옛 글을 보면 닉네임 걸고 글 쓰시면서도 저는 익명으로도 차마 함부로 못할 심한 말씀 하시는 분들도 계시더군요.
CAPTCHA가 조금 번거롭긴 한데 AI가 아닌 사람으로서 그렇게 어려운 것도 아닙니다.

2. 책임의 한계입니다. 오픈 소스 프로젝트 개발자들이 선의로 활동하며 최선을 다하지만 아무런 보증도 하지 못하는 것처럼
저도 최대한 정확하고 유익한 답변을 쓰기 위해 최선을 다하지만 보증할 순 없습니다. 익명으로 답변을 다는 건 그런 표시이기도 합니다.

3. 평판이나 선입견을 배제하고도 신뢰할 수 있는 답변을 달기 위한 노력이기도 합니다.
익명이 쓰는 글은 일반적으로 신뢰를 할 수가 없으니, 텍스트만으로 충분한 신뢰를 얻을 수 있는 글을 쓰는 연습을 하고 있습니다. (출처 표기, 설득력 있는 논리 전개 등)
다른 분들이 제 글을 좀 더 비판적으로 읽어 주시고 평가해주시리라는 것도 저한테 긍정적인 효과입니다. 제가 더 배울 수 있을 테니까요.

Anti-Lock의 이미지

네. 잘 이해되었습니다^^

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.