2014-12-02 8 views
12

Sto facendo due operazioni che coinvolgono atoi e mi chiedo come posso farlo con interi senza segno perché atoi sembra convertirli in firmati causando un overflow di tipo wraparound. Voglio lavorare con interi senza segno a 32 bit ma atoi mi limita in modo efficace a 31 bit senza segno.Equivalente di atoi per interi senza segno

if (multiplication_is_safe(atoi(argv[1]),atoi(argv[3]))) 
    { 
    printf("%s * %s = %u \n", argv[1], argv[3], atoi(argv[1]) * atoi(argv[3])); 
     return 0; 
    } else 
+0

'atoll'? Non sono sicuro che sia una funzione C standard. – mukunda

+0

Se il codice richiede almeno 16 bit senza segno, utilizzare 'unsigned'. Se il codice ha bisogno di almeno 32 bit senza segno, usa 'unsigned long'. Se il codice necessita di unsigned a 32 bit, usa 'uint32_t'. – chux

risposta

14

la risposta è semplice da usare strtoul() invece.

La risposta più lunga è che anche se tutto ciò di cui si ha bisogno è stato firmato con numeri interi a 32 bit o contento di 31 bit per non firmato, la funzione atoi() è inadatta per ciò che si sta facendo.

Come già notato, la funzione atoi() converte una stringa in un numero intero. Un numero intero normale e firmato. Tuttavia, quello che atoi()non fa do è la gestione degli errori. Che atoi() 's specifiche dicono è 'Se il valore non può essere rappresentato, il comportamento è indefinito.'

Lo strto *() famiglia di tutte le funzioni di specificare chiaramente come gli errori vengono gestiti, quindi è necessario in tutti i casi, sostituire atoi() con chiamate a strtol() (conversione stringa a lunga), e in questo caso poiché si desidera gestire numeri interi senza segno, è necessario utilizzare strtoul() (convertire la stringa in unsigned long).

Si noti inoltre che se si desidera gestire numeri più grandi, ci sono le funzioni strtoll() e strtoull(), per convertire la stringa in una lunga lunga o una lunga non firmata. (E se si desidera solo per gestire i più grandi valori integrali possibili senza preoccuparsi con tutta quella roba in mezzo, c'è strtoimax() e strtoumax(), che i valori di ritorno di tipo intmax_t o uintmax_t rispettivamente.)

POSIX Documentazione:

2

A seconda della piattaforma, strtoul è probabilmente quello che si vuole: la funzione

Lo strtoul() converte la parte iniziale della stringa in nptr un valore unsigned long int secondo la data base, che deve essere compresa tra 2 e 36, caratterizzato o essere il valore speciale 0.