2012-02-21 9 views
7

Następujący kod działa inaczej na 64-bitowym i 32-bitowym, co powoduje problemy z przeniesieniem kodu.strtok na maszynach 64-bitowych

char * tmp = "How are you?"; 
printf("size of char * = %ld and size of strtok return val = %ld \n",sizeof(char *),sizeof(strtok(tmp," "))); 

Poniżej znajduje się wyjście:

32 bit: 
size of char * = 4 and size of strtok return val = 4 

64 bit: 

size of char * = 8 and size of strtok return val = 4 

Strona człowiekiem strtok mówi:

#include <string.h> 

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

RETURN VALUE 
     The strtok() and strtok_r() functions return a pointer to the next token, or NULL if there are no more tokens. 

char * na maszynie 64 bitowej ma być 8 bajtów jako wydrukowany. Dlaczego więc strtok zwraca 4-bitowy wskaźnik char na maszynie 64-bitowej?

Dzięki

+2

Którego kompilatora używasz do uzyskania tych wyników? – Joel

+5

Zapomniałeś dołączyć ''? Wtedy kompilator może być w tradycyjnym nastroju i przyjmie typ zwracający 'int' dla funkcji, których nie zna. –

+2

Potwierdzono na 'gcc-4.5.real (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2'. Zwariowany. – sarnold

Odpowiedz

9

Zapomniałeś #include <string.h>.

Powoduje to, że domyślny typ powrotu int zostanie wywnioskowany przez kompilator. Poprzez #włączenie prawego pliku nagłówkowego, poprawny prototyp jest wciągany do zakresu.

To rozwiązuje problem dla mnie na gcc. Jeśli to nie dla ciebie, jakiego kompilatora używasz?

+1

Twój kompilator * powinien * przynajmniej ostrzec cię, jeśli spróbujesz zadzwonić do niezadeklarowanej funkcji. Jeśli nie, musisz dowiedzieć się, jak zwiększyć poziom ostrzeżenia. (Niejawna reguła int została usunięta z języka przez normę ISO C z 1999 r.) I w komentarzu OP stwierdza, że ​​zawiera on 'string.h'; jeśli tak, to nie jest problem. –

+0

Przepraszamy za kłopot. W hierarchii plików miałem kopię pliku string.h. Usunąłem string.h i niech gcc przyjmie domyślną ścieżkę. Teraz działa. @ Daniel, Clark: Dzięki za podpowiedź !! – ntalli

+0

@ntalli: dyrektywa include musi zawierać '#include ', * not * '#include" string.h "'; które powinno unikać przechwytywania nagłówka 'string.h' z własnej hierarchii plików. I zdecydowanie powinieneś naprawić łańcuch formatu 'printf', jak opisałem w mojej odpowiedzi. Skompiluj z 'gcc -std = c99 -pedantic -Wall -Wextra', aby uzyskać lepsze ostrzeżenia. (Zamień '-std = c99' na' -ansi', jeśli chcesz kod C89/C90 zamiast C99.) –

3

Wywołanie strtok(tmp, " ") spowoduje zachowanie niezdefiniowane, ponieważ byłoby próbować zmodyfikować ciąg dosłownego że tmp wskazuje - ale ponieważ operand sizeof nie jest analizowany (z jednym wyjątkiem, że nie stosuje się tutaj), że nie jest to kwestia.

Prawdziwy problem polega na tym, że próbujesz wydrukować wartości size_t w formacie "%ld", co wymaga argumentu unsigned long.

Jeśli implementacja wspiera go, poprawny format dla size_t argumentem jest "%zu" (dodane w C99):

printf("size of char * = %zu and size of strtok return val = %zu\n", 
     sizeof(char *), sizeof(strtok(tmp," "))); 

przeciwnym razie jawnie przekonwertować argumenty do odpowiedniego rozmiaru. Chciałbym użyć "%lu", ponieważ size_t jest typu unsigned.

printf("size of char * = %lu and size of strtok return val = %lu\n", 
     (unsigned long)sizeof(char *), (unsigned long)sizeof(strtok(tmp," "))); 

Oto pełna samowystarczalny program, który powinien przynieść oczekiwanych rezultatów na każdym C89 lub późniejszej realizacji:

#include <stdio.h> 
#include <string.h> 
int main(void) { 
    char * tmp = "How are you?"; 
    printf("size of char * = %lu and size of strtok return val = %lu\n", 
      (unsigned long)sizeof(char *), 
      (unsigned long)sizeof(strtok(tmp," "))); 
    return 0; 
} 

EDIT: Komentarz PO jest po drugiej odpowiedź wskazuje, że string.h nagłówek był problemem; widocznie miał

#include "string.h" 

zamiast

#include <string.h> 

mam zamiar opuścić tę odpowiedź, bo to opisuje inny problem, który musi zostać rozwiązany w kodzie PO, choć nie jedynym, który spowodował zaobserwowany objaw. i kompilator pobrał zły plik nagłówkowy string.h.

+0

Chciałbym wiedzieć, że wyjątek do 'sizeof()', który nie ma tutaj zastosowania. :) – sarnold

+0

Nie mogę uwierzyć, że niepoprawny specyfikator formatu spowodowałby wydrukowanie wartości 8 jako 4, gdy oba, oczekiwane, że przekazany typ to 64-bitowe liczby całkowite. –

+0

@sarnold Tablice o zmiennej długości? –

Powiązane problemy