2012-02-21 13 views
7

Il seguente codice funziona in modo diverso su 64 bit e su 32 bit, il che mi causa problemi nel trasferire il mio codice.strtok su macchine a 64 bit

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

Ecco l'output:

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 

La pagina man di strtok dice:

#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. 

Il char * su una macchina a 64 bit dovrebbe essere 8 byte come stampato. Allora perché strtok restituisce un puntatore char da 4 byte su una macchina a 64 bit ??

Grazie

+2

Quale compilatore stai usando per ottenere questi risultati? – Joel

+5

Hai dimenticato di includere ''? Quindi il compilatore potrebbe essere nell'umore tradizionale e assumere il tipo restituito 'int' per funzioni che non conosce. –

+2

Confermato in 'gcc-4.5.real (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2'. Pazzo. – sarnold

risposta

9

ti sei dimenticato di #include <string.h>.

Questo sta causando il tipo di ritorno predefinito di int da dedurre dal compilatore. Con #includendo il file di intestazione corretto, il prototipo corretto viene inserito nell'ambito.

Questo risolve il problema per me su gcc. Se non fa per te, quale compilatore stai usando?

+1

Il tuo compilatore * dovrebbe * almeno avvisarti se provi a chiamare una funzione non dichiarata. In caso contrario, è necessario scoprire come aumentare il livello di avviso. (La norma implicita int è stata rimossa dalla lingua dallo standard ISO C del 1999.) E in un commento, l'OP dice che includeva 'string.h'; se è così, non è questo il problema. –

+0

Ci scusiamo per il disturbo. Ho avuto una copia di string.h nella mia gerarchia di file. Ho cancellato la stringa.h e ho lasciato che gcc prendesse il percorso predefinito. Ora funziona. @ Daniel, Clark: Grazie per il suggerimento !! – ntalli

+0

@ntalli: la direttiva include deve essere '#include ', * not * '#include" string.h "'; che dovrebbe evitare di raccogliere un'intestazione 'stringa.h' dalla propria gerarchia di file. E sicuramente dovresti risolvere la stringa di formato 'printf', come ho descritto nella mia risposta. Compilare con 'gcc -std = c99 -pedantic -Wall -Wextra' per ottenere avvisi migliori. (Sostituisci '-std = c99' con' -ansi' se vuoi il codice C89/C90 piuttosto che C99.) –

3

Calling strtok(tmp, " ") causerebbe un comportamento indefinito, in quanto sarebbe tentare di modificare la stringa letterale che tmp punti a - ma dal momento che l'operando di sizeof non viene valutato (con una sola eccezione che non si applica qui), questo non è un problema.

Il vero problema è che si sta tentando di stampare valori size_t con un formato "%ld", che richiede un argomento unsigned long.

Se l'implementazione supporta, il formato corretto per un argomento size_t è "%zu" (aggiunto in C99):

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

In caso contrario, convertire in modo esplicito gli argomenti alla dimensione appropriata. Vorrei usare "%lu", poiché size_t è un tipo senza segno.

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

Ecco un programma completo autonomo che dovrebbe produrre i risultati attesi in qualsiasi C89 o poi applicazione:

#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: commento del PO d'altra risposta indica che il string.h l'intestazione era il problema; a quanto pare aveva

#include "string.h" 

piuttosto che

#include <string.h> 

ho intenzione di lasciare questa risposta qui perché descrive un altro problema che deve essere risolto nel codice del PO, anche se non quello che ha causato il sintomo osservato e il compilatore ha prelevato il file di intestazione string.h errato.

+0

Mi piacerebbe conoscere l'eccezione a 'sizeof()' che non si applica qui. :) – sarnold

+0

Non riesco a convincermi che un identificatore di formato errato farebbe sì che il valore di 8 sia stampato come 4 quando entrambi, si prevede che un tipo passato sia costituito da numeri interi a 64 bit. –

+0

@sarnold Array di lunghezza variabile? –

Problemi correlati