2015-03-11 2 views
-1

Я пишу простую программу, чтобы попытаться реализовать strtok. Просто некоторые практики для себяФункция как-то возвращается дважды с одного вызова

Я пришел с этим:

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

char * stringtok(char * str, char * delim){ 
    static int last; 
    if(str != NULL){ last = 0; } 
    char * finder; 
    char * result = malloc(100); 
    while(delim[0] != '\0'){ 
     if(finder = strchr(str+last, delim[0])){ 
      memcpy(result, str + last, finder - str); 
      result[finder-str+1] = '\0'; 
      last = finder - str; 
      return result; 
     } 
     delim++; 
    } 
    return NULL; 
} 

int main(){ 
    char input[100]="This is my - message - hello can - you hear me?"; 
    char input2[100] = "-"; 
    char * pch; 




    pch = stringtok(input, input2); 
    while(pch != NULL){ 
     printf("%s\n", pch); 
     pch = strtok(NULL, input2); 
    } 
} 

Когда я ./a.out с GCC -ggdb, я получаю: «Это мой» Что было странно, так что я побежал это через GDB с точки останова 22 и я получил:

Breakpoint 1, main() at strtok.c:22 
22  int main(){ 
(gdb) s 
23   char input[100]="This is my - message - hello can - you hear me?"; 
(gdb) 
29 
(gdb) 
stringtok (
    str=0x7fffffffe040 "This is my - message - hello can - you hear me?", 
    delim=0x7fffffffdfd0 "-") at strtok.c:7 
7   if(str != NULL){ last = 0; } 
(gdb) 
9   char * result = malloc(100); 
(gdb) 
10   while(delim[0] != '\0'){ 
(gdb) 
11    if(finder = strchr(str+last, delim[0])){ 
(gdb) 
12     memcpy(result, str + last, finder - str); 
(gdb) 
13     result[finder-str+1] = '\0'; 
(gdb) 
14     last = finder - str; 
(gdb) 
15     return result; 
(gdb) 
19   return NULL; 
(gdb) 
main() at strtok.c:30 
30   pch = stringtok(input, input2); 
(gdb) 
31   while(pch != NULL){ 
(gdb) 
This is my 
32    printf("%s\n", pch); 
(gdb) 
30   pch = stringtok(input, input2); 
(gdb) 
34   } 
(gdb) 
0x000000363d21ed5d in __libc_start_main() from /lib64/libc.so.6 
(gdb) 
Single stepping until exit from function __libc_start_main, 
which has no line number information. 

Program exited normally. 
(gdb) 

Я нахожу это очень странным, что у меня есть обратный результат, а затем дополнительно возвращает NULL после, и я не совсем уверен, почему это происходит. Я просто читаю gdb неправильно? Похоже, что он возвращается из результата возврата, чтобы немедленно вернуть NULL. Также похоже, что мой gdb выводит строки 1 линии поздно, глядя на printf, и где на самом деле был выход

+0

Вы уверены, что gdb не просто прыгает до конца функции? Вы пробовали распечатать фактический результат? 'return' -' return'. Он никогда не «возвращает» – John3136

+1

Это НЕ, как работает strtok(). strtok изменяет исходную строку, заменив (вызовом по вызову) некоторый найденный разделитель с '\ 0'. если в оставшейся строке не обнаружен разделитель, верните NULL. Он сохраняет ptr для следующего символа после замененного разделителя в статической памяти. если переданный в первом параметре NULL, он использует сохраненный указатель, в противном случае он использует переданный в указателе из первого параметра. Опубликованный код добавляет требование, чтобы вызывающий пользователь возвращал возвращаемый указатель из опубликованного кода после каждого вызова. Это не то, что делает strtok. – user3629249

+0

, когда параметр 'str' равен NULL, эта строка: if (finder = strchr (str + last, delim [0])) {'- это память доступа на некотором смещении от адреса 0. Это неопределенное поведение и может/приведет к событию сбоя seg. – user3629249

ответ

0

Ваша функция strtok не обрабатывает str, являющийся NULL должным образом. При первом вызове вам нужно сохранить строку в дополнение к последнему смещению. Прямо сейчас, когда вы вызываете его во второй раз, у вас нет указателя на исходную строку в любом месте.

Смежные вопросы