Túnel do Tempo: a função itoa()

Em uma discussão no fórum de Programação em C e C++ do Viva o Linux, seu proponente perguntava acerca da função itoa(), desejoso de compreender seu funcionamento. Julguei interessante transportá-la, com algumas melhorias, para este espaço, até porque aqui posso fazer algo que não posso fazer naquele fórum, que é dar um exemplo explícito da implementação com código fonte em C.

[ Hits: 16.259 ]

Por: Paulo em 14/06/2017 | Blog: http://unixntools.blogspot.com.br/


A implementação da itoa() do antigo Turbo C (e seus problemas)



A versão de itoa() que aparece no código mostrado pelo nosso amigo se parece com a implementação que havia nos antigos compiladores da Borland para o MS-DOS, tais como o Turbo C e seus sucessores. Ela converte um número inteiro para strings de caracteres, contendo os algarismos usados para representar o número de acordo com uma base de numeração informada, a qual podia variar de 2 a 36. Para bases N entre 2 e 10, os algarismos usados eram os primeiros N algarismos do conjunto {'0', '1', '2', ... '9'}. Para bases entre 11 a 36, as letras maiúsculas do ASCII eram usadas também como algarismos, com 'A' valendo 11, 'B' valendo 12, e assim por diante, até 'Z' valendo 35.

Mas a implementação da Borland tinha alguns problemas. Entre eles, destacam-se os seguintes:
  • Não fazer parte da biblioteca de funções padronizadas do C. Isso limitava seu uso apenas a compiladores da Borland e a algumas outras variações que se esforçavam para ser compatíveis com ele, principalmente no mundo MS-DOS. No Linux e nos Unixes em geral, bem como em várias implementações de compiladores C para Windows, essa função não é reconhecida.
  • A função não detectava nem sinalizava erros, tais como valor inválido da base ou ponteiro inválido para a string de saída.
  • Como caso particular de falta de detecção de erros, e com impacto de segurança, está o fato de que a função não permitia reconhecer se a string informada tinha espaço suficiente para acomodar a conversão do número. A documentação da função até dizia que o programador deveria se certificar disso, mas a própria função não tinha como fazer qualquer verificação que garantisse esse cuidado.

Note que, ao executar o programa mostrado pelo nosso colega que fez a pergunta, se o usuário digitar um número maior que ou igual a 512, o programa vai dar problema, pois a conversão vai extrapolar o tamanho do array de caracteres binário, que foi declarado com apenas dez elementos.

A função da biblioteca padrão do C mais indicada para converter números para strings é snprintf(). No caso de números inteiros, a conversão pode ser feita para representações do número em base decimal, octal ou hexadecimal, através das conversões "%d", "%o" e "%x", respectivamente.

Infelizmente, porém, as funções da família de printf() não produzem saída em base binária nem, de modo mais geral, numa outra base qualquer (sujeita a limites mínimo e máximo), como a itoa() do Turbo C permitia fazer. Curiosamente, a função padronizada strtol(), que faz a operação inversa de conversão de string para inteiro, aceita como base de representação um valor qualquer na faixa de 2 a 36, que são os mesmos limites de itoa(), e strings de entrada formadas pelos mesmos caracteres que itoa() teria produzido como saída.

Página anterior     Próxima página

Páginas do artigo
   1. Apresentação do problema
   2. A implementação da itoa() do antigo Turbo C (e seus problemas)
   3. Alguns conceitos para a implementação da função
   4. Algoritmo para formação do numeral a partir do valor do número
   5. "my_itoa()", uma implementação segura de conversão de número em string
   6. Variações de "my_itoa()"
   7. Conclusão
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Detectando assalto na multidão com visão computacional

Criação e uso de um interpretador de script BrainFuck em C++

Substituindo a biblioteca conio.h no Linux usando ncurses curses.h

Criando um sistema operacional com ASM e C++

Utilizando a biblioteca NCURSES - Parte III

  
Comentários
[1] Comentário enviado por uNclear em 19/06/2017 - 01:55h

ótimo artigo, quando tiver tempo vou fazer alguns testes

[2] Comentário enviado por uilianries em 19/06/2017 - 11:23h

Muito bem detalhado. Parabéns pelo conteúdo, Paulo.

[3] Comentário enviado por Nick-us em 01/03/2019 - 20:08h

Valeu a pena ler e guardar! informação nunca é demais!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts