2016-07-18 8 views
-1

Ich versuche, die strtoul Funktion zu verwenden, aber wie unten, damit er zurückkehrt, einen unerwarteten Wert (Zugabe von FFs am Anfang) gezeigt:strtoul geben unerwarteten Ausgang

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

main() { 
    unsigned long temp ; 
    char *err; 
    temp = strtoul("3334444444",&err,10); 
    if (temp > UINT_MAX) { 
     printf("%lx %x %x\n",temp,3334444444,UINT_MAX); 
    }else 
     printf("%lx %x\n",temp,3334444444); 
} 

$./a.out 
ffffffffc6bf959c c6bf959c ffffffff 

Die obige Ausgabe entspricht dem if Teil sein stimmt, obwohl ich erwarte, dass der else Teil hier ausgeführt wird. Kann mir bitte jemand erklären, warum sich strtoul so verhält? Warum gibt es ffffffffc6bf959c statt nur c6bf959c zurück? Wenn ich "333444444" (d. H. Nur ein 4 weniger) anstelle von "3334444444" in dem obigen Code verwende, dann erhalte ich die korrekte Ausgabe (d. H. 13dff55c 13dff55c), die dem else Teil entspricht.

Note : As pointed by melpomene in his reply below, stdlib.h header file should have been included and that will resolve the issue. Can anyone please let me know what is being done by the program by assuming the incorrect return type (int in this case) during compile time which can't be undone (or atleast it is not getting undone in this case) even after knowing the correct return type (unsigned long in this case) during link time ? In short, i want to know how c6bf959c is getting converted to ffffffffc6bf959c because of prototype not provided.

+0

hast du versucht strtoull anstelle von strtoul? – bruceg

+0

Ich bekomme Ihr erwartetes Verhalten mit diesem Code. Was ist deine Umgebung? –

+0

'ULONG_MAX' hat dieselbe Größe wie' UINT_MAX' auf 32-Bit-Systemen. 'strtoull' wäre besser, wie Brueg sagte. – yellowantphil

Antwort

6

mit gcc Code Kompilieren mit Warnungen aktiviert gibt:

try.c:5:1: warning: return type defaults to ‘int’ [-Wimplicit-int] 
main() { 
^~~~ 
try.c:5:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes] 
try.c: In function ‘main’: 
try.c:8:12: warning: implicit declaration of function ‘strtoul’ [-Wimplicit-function-declaration] 
    temp = strtoul("3334444444",&err,10); 
      ^~~~~~~ 
try.c:8:5: warning: nested extern declaration of ‘strtoul’ [-Wnested-externs] 
    temp = strtoul("3334444444",&err,10); 
    ^~~~ 
try.c:10:22: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 3 has type ‘long long int’ [-Wformat=] 
     printf("%lx %x %x\n",temp,3334444444,UINT_MAX); 
        ^
try.c:12:22: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 3 has type ‘long long int’ [-Wformat=] 
     printf("%lx %x\n",temp,3334444444); 
        ^

Das Hauptproblem ist implicit declaration of function ‘strtoul’, was darauf hinweist, dass die Funktion nicht deklariert wird (und damit zurück int angenommen), weil Sie vergessen haben, zu #include <stdlib.h>. Hinzufügen der fehlenden #include behebt den Wert temp.

Aber Sie sollten sich auch die Warnungen für printf ansehen und diese beheben.

+1

Außerdem wird 'temp> UINT_MAX' niemals auf (normalen) 32-Bit-Systemen wahr sein. – yellowantphil

+0

@melpomene: stimmte zu, dass die Headerdatei stdlib.h enthalten sein sollte. Können Sie mir bitte mitteilen, was das Programm macht, indem Sie während der Kompilierzeit den falschen Rückgabewert (int in diesem Fall) annehmen, der nicht rückgängig gemacht werden kann (oder zumindest in diesem Fall nicht rückgängig gemacht wird) korrekter Rückgabewert (in diesem Fall vorzeichenlos lang) während der Verbindungszeit? – mezda

+0

@yellowantphil: Kannst du ein wenig erklären, warum es niemals wahr sein wird? temp ist ein unsigned long und kann größer als uint_max sein. unsigned long kann auch auf 32-Bit-Systemen 8 Bytes lang sein. Recht ?? – mezda