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.201 ]
Por: Paulo em 14/06/2017 | Blog: http://unixntools.blogspot.com.br/
#include <errno.h> #include <limits.h> #include <stddef.h> #include <stdint.h> char *my_umaxtoa(uintmax_t n, char *str, size_t str_size, uint8_t base){ static const char symbols[36]={ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; uintmax_t quot, rem; char rev_str[CHAR_BIT*sizeof(uintmax_t)]; int rev_str_len=0; if(base<2 || base>sizeof symbols){ // Base inválida? errno=EINVAL; return NULL; } if(str_size<2){ // String de saída pequena demais? errno=ERANGE; return NULL; } do { quot=n/base; rem=n-quot*base; rev_str[rev_str_len++]=symbols[rem]; // Seleciona o algarismo correspondente ao resto. if(rev_str_len>str_size-1){ // String de saída pequena demais? errno=ERANGE; return NULL; } n=quot; } while(quot>0); do *str++=rev_str[--rev_str_len]; // Copia dígitos da string reversa para a ordem natural na saída. while(rev_str_len>0); *str='\0'; // Coloca o byte nulo terminador da string de saída. return str; } char *my_imaxtoa(intmax_t n, char *str, size_t str_size, uint8_t base){ if(n<0){ // Trata número negativo (ver nota). *str++='-'; str_size--; n=-n; } return my_umaxtoa(n, str, str_size, base); // Reaproveita a conversão sem sinal. }
#include <algorithm> #include <stdexcept> #include <string> #include <type_traits> #include <cerrno> #include <climits> #include <cstring> template <class T> std::string my_itoa(T n, uint8_t base){ static const char symbols[36]={ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; if(std::is_signed<T>::value && n<0) return '-'+my_itoa(typename std::make_unsigned<T>::type(-n), base); if(base<2 || base>sizeof symbols) // Base inválida? throw std::runtime_error(std::strerror(errno)); std::string result; std::string rev_str; T quot, rem; rev_str.reserve(CHAR_BIT*sizeof(T)); do { quot=n/base; rem=n-quot*base; rev_str+=symbols[rem]; // Seleciona o algarismo correspondente ao resto. n=quot; } while(quot>0); result.resize(rev_str.length()); std::copy(rev_str.rbegin(), rev_str.rend(), result.begin()); return result; }
Gerencie suas contas financeiras pessoais com Terminal Finances
Programando com uma granada de mão: uma visão da linguagem C
LivreNFE - O emissor Nfe open source para Linux
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
Não to conseguindo resolver este problemas ao instalar o playonelinux (1)
Excluir banco de dados no xampp (1)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta