strtok_r 과 strtok 의 차이점?

jai의 이미지

솔라리스 8.0 입니다.

#include <stdio.h>
#include <strings.h>

int main(int argc, char *argv[]) 
{
    const char delim[] = "\t\n =";
    char    *buf, *value_p, *lasts;
    char str[]="thsis is test";

    buf = str;
    //value_p = strtok_r(buf, delim, &lasts); 1번 
    value_p = strtok(buf, delim); 2번
    if( !value_p ){
        fprintf(stderr, "wrong string \n");
        return(-1);
   }
        
    fprintf(stdout, "string token is %s\n", value_p);
    return(0);
}

1번으로 컴파일하면
"strtok_test.c", line 13: warning: improper pointer/integer combination: op "="
이러한 워닝이 나옵니다.

2번으로 컴파일하면 아무런 워닝이 없습니다.

두 함수에 어떤 차이가 있는 건가요?

crimsoncream의 이미지

_r이 붙으면 reentrant 함수로 thread safe 한 놈입니다.

man strtok

하시면 더할 나위없이 자세히 설명이 나오는데요.
혹시 glibc 관련 man 페이지를 설치 안하신건가요 :)

   value_p = (char *)strtok_r(buf, delim, &lasts); 

그리고 혹시 이러면 괜찮지 않나요?

편집하고 있었는데.. 벌써 쓰신 분이 계시네요 :)
위에처럼 해서 잘 된다면 strtok_r에 대한 선언이 없어서 return type을 int로 가정하게되서 생기는 워닝입니다.

오늘 우리는 동지를 땅에 묻었습니다. 그러나 땅은 이제 우리들의 것입니다.
아직도 우리의 적은 강합니다. 그러나 우리는 그들보다 많습니다.
항상 많을 것입니다.

장준영의 이미지

warning이 나오는 이유는, strtok_r 에 대한 원형(prototype)이
포함되지 않았기 때문입니다.
단순히 strings.h (정확히는 string.h)를 include 한다고 해서
strtok_r 에 대한 함수 원형이 포함되지 않습니다.
/usr/include/string.h를 열어서 살펴보세요.

jai의 이미지

급한 마음에 질문을 잘못 올렸습니다. 죄송합니다.

두 함수의 차이가 아니라, 같은 변수들을 사용했는데 결과가 다른 이유를 여쭤보려고 했던 것입니다.

검색하다 보니 어떤 분이 HP 에서 64 bit 로 컴파일 했을 때 저와 비슷한 에러가 나왔더군요. 저도 64bit 로 컴파일이 되기에, 그 분이 기재하신 방법으로 저도 해봤습니다.
-> 64bit 로 컴파일 할 때 에러가 났다고 해서, 저도 그런줄로 알았습니다. 워닝과는 관계가 없는 부분이었네요.^^

프로그램 시작전에
char *strtok_r();
를 선언해 주면 워닝 메세지 없이 컴파일이 됩니다.

해결은 됐지만, 이런 차이가 나는 원인을 모르겠습니다.
함수 선언과 improper pointer/integer combination: op "=" 워닝 메세지와 어떤 상관관계가 있는 것인지 조언 바랍니다.
-> 제가 답글이 늦었네요. 감사합니다.

peace :)

jai의 이미지

말씀해주신 것처럼 /usr/include/string.h 파일을 살펴봤습니다.

한가지만 더 여쭤볼께요.

그 헤더 파일에 정의된 내용을 보면,
코드:

#if defined(__STDC__)

#if defined(__EXTENSIONS__) || defined(_REENTRANT) || \
(_POSIX_C_SOURCE - 0 >= 199506L)
extern char *strtok_r(char *, const char *, char **);
#endif /* defined(__EXTENSIONS__) || defined(_REENTRANT) .. */
...(생략)
#else /* __STDC__ */

#if defined(__EXTENSIONS__) || defined(_REENTRANT) || \
(_POSIX_C_SOURCE - 0 >= 199506L)
extern char *strtok_r();
#endif /* defined(__EXTENSIONS__) || defined(_REENTRANT).. */

위 내용을 보아 세 종류로 컴파일 해봤습니다.
1. .c 파일내에
#define _REENTRANT__ 혹은 #define _REENTRANT 를 기재한 뒤
#include 합니다.

2. cc -D 플래그 옵션으로 넣었습니다.
cc -D_REENTRANT -o strtok_test strtok_test.c
혹은
cc -D__EXTENSIONS__ -o strtok_test strtok_test.c

3. 앞글에서 적은 것처럼 플래그를 사용하지 않고,
char *strtok_r();
혹은
char *strtok_r(char *, const char*, char **);

그런데 extern 인자가 있는 것과 없는 것은 차이를 갖습니까?
제 생각에는 차이가 있어서 , string.h 헤더파일이 두 경우를 나눠서 적은 게 아닐까 싶은데요?

peace :)

ohhara의 이미지

_r과 같이 reentrant한 function을 사용해서 multi thread safe한 programming을 할 때는 -D_REENTRANT 를 compile시에 넣어주지 않으면 compile이 된다 하더라도 정상적인 작동은 보장할 수 없습니다.

오래된 c compiler에서는 function prototype을 declare할 때 argument를 적어주면 compile error가 발생합니다. 요즘 c compiler는 argument를 적어줘도 compile error가 발생하지 않습니다. 여러 환경에서 compile을 하기 위해 저렇게 header file을 작성합니다.

Taeho Oh ( ohhara@postech.edu ) http://ohhara.sarang.net
Postech ( Pohang University of Science and Technology ) http://www.postech.edu
Alticast Corp. http://www.alticast.com

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.