strtok함수 질문입니다.

canuyes의 이미지

C++ 입문자입니다.

strtok 함수를 사용도중 궁금한 점이 생겨 글 올립니다.
평소 strtok의 원리는 생각하지 않으려 하고
그냥 strtok함수의 프로토 타입만을 외우다시피하여 사용해 왔습니다.

char temp[100]="Like C++";
char* str;
str=strtok(temp," ");
while(str!=NULL){
	str=strtok(NULL," ");
	cout<<str<<endl;
}

와 같은 형식으로 사용해 왔습니다.

오늘 스택계산기 설계도중

char temp[100]="Like C++";
char* str;
str=strtok(temp," ");
while(str!=NULL){
	str=strtok(NULL," ");
	/*
		something
	*/
	cout<<str<<endl;
}

위의 주석부분에 추가적으로 코딩해야 할 일이 생겼습니다.

굳이 예를 들자면

char temp[100]="Like C++";
char* str;
str=strtok(temp," ");
while(str!=NULL){
	str=strtok(NULL," ");
	cout<<str[0]<<endl;
	cout<<str<<endl;
}

과 같은 형식이었습니다.

차이점은 cout< 이 라인을 삽입하지 않았을 때는 컴파일 및 실행 시에 정상 종료되고,
삽입하였을 때는 컴파일 및 실행 시에 정상종료 되지 않습니다.

현재 저는 dev-c++을 사용중입니다.
dec-c++에서 컴파일은 정상적으로 진행되고,
웹 컴파일러에서 컴파일 시에는 segmetation fault 가 뜹니다.
오류의 원인과 strtok 함수의 원리를 알고 싶습니다.

qiiiiiiiip의 이미지

1.
c++을 처음 공부하시려는것 같은데,
c++을 "공부"하시려면 strtok, char* 같은걸 멀리하세요.
c++의 철학과는 거리가 먼 함수/타입니다.
c++ 질문에 답을 드려야할지, strtok사용법에 답변을 드려야할지
망설여지네요.

2.
컴파일과 실행(런타임)이라는 단어를 구분해서 사용해주세요.
컴파일 시 seg fault가 뜰리가요.

3.
strtok 사용의 전형적인 예는 아래와 같습니다.

char temp[100]="Like C++";
char* str;
str=strtok(temp," ");
while(str!=NULL){
	cout<<str<<endl;
	str=strtok(NULL," ");
}

님께서 처음 올리신 코드와 어떻게 다른지 살펴보세요.
이것이 오류의 원인입니다.

4.
strtok의 원리는 게시판에 질문하기에 적절한 주제가 아닙니다.
찾아보시면 얼마든지 널려있습니다.

empty2fill의 이미지

저는 어떤 질문이든지 환영합니다.

오류의 원인은 NULL 체크를 하지 않았기 때문입니다.

두번째 루프에서 strtok이 NULL을 리턴하고 이 값을 str에 저장 하셨죠?

그리고 str[0]으로 잘못된 메모리(주소가 NULL(0)인)에 접근을 하려고 했기 때문에

Segmentation fault 에러가 난것입니다.


strtok의 함수 선언을 보시면 리턴 타입이 char* 형입니다. 즉 포인터를 리턴하는 거죠.

char *strtok(char *str, const char *delim);

strtok의 리턴 값은 다음 토큰의 시작 주소를 리턴하고 다음 토큰이 없는 경우 NULL을 반환 하게 되어있습니다.


그런데 이상하죠?

cout<<str<<endl;

으로 null 포인터를 출력하는게 문제가 없다니...

null 포인터를 cout으로 출력하는 동작은 규격상 정의 되지 않았다고 하네요(undefined behavior).

따라서 컴파일러에 따라 다르게 정의 할 수 있는데요.

제가 테스트한 gcc도 그렇고 dev-c++도 아무 출력도 내지 않도록 되어있나봐요.


추신 : 함수의 동작까지는 자세히 이해하지 못하더라도 input과 ouput은 정확히 알고 사용하는 습관을 들이시면 좋습니다. 저도 C++을 Like 합니다^^


[참고] 정보: strtok(): C 함수--보충 설명서

http://support.microsoft.com/kb/51327/ko

——
———
Life is a tragedy when seen in close-up, but a comedy in long-shot. - Chaplin, Charlie -

댓글 달기

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