Estou tentando descobrir se existe uma maneira alternativa de converter seqüência de caracteres para número inteiro em c.
Costumo padronizar o seguinte no meu código.
char s[] = "45";
int num = atoi(s);
Então, existe uma maneira melhor ou outra?
Respostas:
Existe o
strtol
que é melhor IMO. Também gosteistrtonum
, então use-o se você o tiver (mas lembre-se de que não é portátil):EDITAR
Você também pode estar interessado
strtoumax
estrtoimax
quais são as funções padrão no C99. Por exemplo, você poderia dizer:De qualquer forma, fique longe de
atoi
:fonte
strtonum
? Eu continuo recebendo um aviso de declaração implícita ##<stdlib.h>
. No entanto, você pode usar astrtoumax
alternativa padrão .strtol
Solução robusta baseada em C89Com:
atoi
família)strtol
(por exemplo, nenhum espaço em branco à esquerda nem caracteres de lixeira à direita)GitHub upstream .
Baseado em: https://stackoverflow.com/a/6154614/895245
fonte
str2int()
. Pedante: usoisspace((unsigned char) s[0])
.(unsigned char)
elenco pode fazer a diferença?l > INT_MAX
el < INT_MIN
faz uma comparação inteira sem sentido, pois qualquer um dos resultados é sempre falso. O que acontece se eu os alterarl >= INT_MAX
el <= INT_MIN
apagar os avisos? No ARM C, long e int são tipos de dados básicosl >= INT_MAX
funcionalidade incorreta: Exemplo retornandoSTR2INT_OVERFLOW
com entrada"32767"
e 16 bitsint
. Use uma compilação condicional. Exemplo .if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX)) return STR2INT_OVERFLOW;
seria melhor comoif (l > INT_MAX || (errno == ERANGE && l == LONG_MAX)) { errno = ERANGE; return STR2INT_OVERFLOW;}
para permitir que o código de chamada para usarerrno
emint
fora-de-gama. O mesmo paraif (l < INT_MIN...
.Não use funções do
ato...
grupo. Estes estão quebrados e praticamente inúteis. Uma solução moderadamente melhor seria usarsscanf
, embora também não seja perfeita.Para converter string em número inteiro, funções do
strto...
grupo devem ser usadas. No seu caso específico, seriastrtol
função.fonte
sscanf
na verdade, possui um comportamento indefinido se tentar converter um número fora do intervalo de seu tipo (por exemplo,sscanf("999999999999999999999", "%d", &n)
).atoi
não fornece feedback significativo de sucesso / falha e possui um comportamento indefinido no estouro.sscanf
fornece feedback de êxito / falha das sortes (o valor de retorno, que é o que o torna "moderadamente melhor"), mas ainda tem um comportamento indefinido no estouro. Somentestrtol
é uma solução viável.sscanf
. (Embora eu confesso que às vezes usamatoi
, geralmente para os programas que eu não esperava sobreviver mais de 10 minutos antes de apagar a fonte.)Você pode codificar um pouco de atoi () por diversão:
Você também pode torná-lo recursivo, que pode ser antigo em 3 linhas =)
fonte
code
((str *) - '0')code
"----1"
2) Tem comportamento indefinido comint
estouro quando o resultado deve serINT_MIN
. Consideremy_getnbr("-2147483648")
Só queria compartilhar uma solução por muito tempo sem assinatura.
fonte
const char *
.48
significa? Você está assumindo que esse é o valor de'0'
onde o código será executado? Por favor, não imponha suposições tão amplas ao mundo!'0'
como deveria.fonte
Você sempre pode rolar o seu próprio!
Isso fará o que você deseja sem confusão.
fonte
strto...
família de funções. Eles são portáteis e significativamente melhores.0x2d, 0x30
vez de'-', '0'
. Não permite'+'
sinal. Por que(int)
lançar(int)strlen(snum)
? UB se a entrada for""
. UB quando o resultado éINT_MIN
devido aoint
estouro comaccum += (snum[strIdx] - 0x30) * pow(10, idx);
Esta função irá ajudá-lo
Ref: http://amscata.blogspot.com/2013/09/strnumstr-version-2.html
fonte
atoi
amigos e é que, se houver excesso, é um comportamento indefinido. Sua função não verifica isso.strtol
e amigos fazem.Se a resposta ajudou de alguma forma, por favor, marque como resposta, caso a sua dúvida não tenha sido solucionada, por favor, poste novamente.
fonte
fonte
nInt = (nInt *= 10) + ((int) snum[index] - 48);
vs.nInt = nInt*10 + snum[index] - '0';
if(!nInt)
não é necessário.No C ++, você pode usar essa função:
Isso pode ajudá-lo a converter qualquer string para qualquer tipo, como float, int, double ...
fonte
Sim, você pode armazenar o número inteiro diretamente:
Se você precisar analisar uma string
atoi
oustrol
vencer o concurso "menor quantidade de código".fonte
strtol()
na verdade , exige uma quantidade razoável de código. Ele pode retornarLONG_MIN
ouLONG_MAX
seja , se é isso o valor convertido real ou se há um estouro negativo ou estouro, e ele pode retornar 0, quer se esse é o valor real ou se não houve número a ser convertido. Você precisa definirerrno = 0
antes da chamada e verificar oendptr
.