Diversas vezes precisamos converter nossos dados para manipulá-los da maneira desejada e até mesmo para dificultar exibição quando necessário.
Nós fizemos algumas dessas conversões do zero no Curso de C++ para Iniciantes sem usar bibliotecas e isso é interessante por fins didáticos para entendermos o que na verdade essas bibliotecas fazem.
Mas, para fins de desenvolvimento é bom já termos algo pronto para agilizarmos, então criei um único arquivo convert.hpp
com uma Union que possui as funções-membro para isso.
Eu realmente não gosto de encher o código de comentários, até porque programadores sabem ler o código da linguagem de programação que ele está familiarizado.
No entanto, vou informar algumas coisas no código para ficar mais fácil a leitura e caso você queira incrementar alguma coisa, ficará mais fácil, são elas:
union
em vez de class
ou struct
por motivos de desempenho como vimos nesse artigo;static
para não precisarmos de instância e utilizar mais facilmente somente com o operador ::
;namespace
, pois a própria static
já permitirá um escopo;ascii_to_bin()
adicionei essa verificação abaixo só para separarmos a saída em 8 bits, exemplo: 01010101 01010101
, ou seja, por um espaço no meio:if( ss.str().length() % 8 == 0){
ss << " ";
}
bin_to_hex()
adicionei o iterador bin.erase( std::remove( bin.begin() , bin.end(), ' ') , bin.end() );
para removermos o espaço em branco dos bits, se houver, pois em bin_to_ascii()
as converões são diferentes;std::bitset<16>
;ascii_to_hex
, reutiliza as outras funções-membro, não precisar reescrever tudo.O código completo é esse:
convert.hpp
#pragma once
#include <sstream>
#include <bitset>
#include <vector>
#include <algorithm>
union conv {
static const std::string bin_to_ascii(const std::string & bin){
std::stringstream ss(bin);
std::string r;
while(ss.good()){
std::bitset<8> bits;
ss >> bits;
char c = char(bits.to_ulong());
r += c;
}
return r;
}
static const std::string ascii_to_bin(const std::string& ascii){
std::stringstream ss(ascii);
for (size_t i = 0; i < ascii.length(); ++i) {
std::bitset<8> bits(ascii[i]);
ss << bits;
if( ss.str().length() % 8 == 0){
ss << " ";
}
}
return ss.str();
}
static const std::string bin_to_hex(std::string bin){
bin.erase( std::remove( bin.begin() , bin.end(), ' ') , bin.end() );
std::bitset<16> bits(bin);
std::stringstream res;
res << std::hex << std::uppercase << bits.to_ulong();
return res.str();
}
static const std::string ascii_to_hex(std::string ascii){
return bin_to_hex( ascii_to_bin(ascii) );
}
};
Para utilizar, basta incluir esse arquivo e chamar as funções-membro estáticas da union, exemplo: conv::funcao_membro(param);
:
main.cpp
#include <iostream>
#include "convert.hpp"
int main(){
std::cout << conv::bin_to_ascii("01001111 01101011") << '\n';
std::cout << conv::ascii_to_bin("Ok") << '\n';
std::cout << conv::bin_to_hex("01001111 01101011") << '\n';
std::cout << conv::ascii_to_hex("Ok") << '\n';
}
Possível e provável saída:
Ok
01001111 01101011
4F6B
4F6B
Se quiser adicionar mais conversões, por exemplo, para: decimal e octal, será um bom exercício. Não pus no GitHub porque é só um arquivo básico! 😃