No ultimo post mostrei as operações básicas com strings como contar caracteres e comparações, agora vamos nos aprofundar um pouco mais.
Primeiramente, como funciona um char? O char em C é um int pequeno (geralmente 8 bits) sinalizado (o char pode ser sinalizado ou não, dependendo da plataforma), a questão é que o char armazena números, e os números representam caracteres. Mas qual número é qual? O Visual (e acho que quase todos compiladores) usam como base a tabela ASCII que define o valor numérico de cada caracter.
Com base nisso, podemos então escrever:
#include <stdio.h>
int main(int, char **)
{
char ola[4];
ola[0] = 111;
ola[1] = 108;
ola[2] = 97;
ola[3] = 0;
printf(ola);
return 0;
}
No código acima inicializamos a string “ola” usando os valores numéricos dela, mas qual a vantagem disso? Nenhuma, na verdade apenas facilitamos a vida do compilador, mas o que pode ser feito de útil com esse conhecimento?
A primeira coisa que pode ser feita é traduzir o outdoor da EA:

Agora vamos supor que seja necessário criar um programa para verificar se uma string possui apenas caracteres de A a Z (caixa alta):
#include <iostream>
bool ehAZ(const char *str)
{
for(int i = 0;str[i]; ++i)
{
if((str[i] < 'A') || (str[i] > 'Z'))
return false;
}
return true;
}
int main(int argc, char **argv)
{
using namespace std;
cout << ehAZ("ABC") << endl;
cout << ehAZ("ABaC") << endl;
cout << ehAZ("!@#$%") << endl;
return 0;
}
Note que na tabela ASCII letras e números estão em sequência, por isso não precisamos nos preocupar em testar todas as letras, podemos testar apenas sequências.
Convertendo para Letras Maiúsculas
Agora vamos ver como fica uma rotina para mudar todas as letras de uma string para maiúsculas:
#include <iostream>
char *toUp(char *str)
{
for(int i = 0;str[i]; ++i)
{
if((str[i] >= 'a') && (str[i] <= 'z'))
str[i] = 'A' + (str[i] - 'a');
}
return str;
}
int main(int argc, char **argv)
{
char str[] = "abCd!@#$456z";
using namespace std;
cout << toUp(str) << endl;
return 0;
}
A função toUp é bem simples, ela percorre a string procurando caracteres que estejam no intervalo de ‘a’ a ‘z’, e quando encontra converte o caractere para sua versão maiúscula. A formula de conversão primeiramente calcula qual o índice da letra sendo convertida (que seria o número da letra no alfabeto, mas começando de zero) e depois soma esse índice ao índice inicial das letras maiúsculas.
Vamos pegar como exemplo a conversão da letra ‘c’, primeiramente é feito str[i] – ‘a’, o que resulta em ‘c’ – ‘a’, chegando em 99 – 97, resultando 2. Na sequência é feito ‘A’ + 2, que significa: 65 + 2 = 67. Consultando a tabela temos: 67 = C.
Apenas para lembrar, já existe uma função na biblioteca padrão para conversão de letras minusculas para maiúsculas chamada toupper, que é declarada em ctype.h. Neste header também existem outras funções do mesmo genero, como: tolower, islower, isupper, etc.
Convertendo para Números
Por fim, vamos ver como converter uma string que contêm um número inteiro para uma variável to tipo int:
#include <iostream>
int myAtoi(const char *str)
{
int len = (int) (strlen(str)-1);
int num = 0;
int dec = 1;
for(;len >= 0; --len)
{
if(str[len] >= '0' && str[len] <= '9')
{
num += dec * (str[len] - '0');
dec *= 10;
}
else if((len == 0) && (str[len] == '-' || str[len] == '+'))
num = (str[0] == '-') ? -num : num;
else
{
//numero invalido, entao 0
return 0;
}
}
return num;
}
int main(int argc, char **argv)
{
using namespace std;
int num = myAtoi("23");
cout << num << endl;
cout << myAtoi("-10") + myAtoi("5") << endl;
return 0;
}
A função myAtoi processa a string e retorna o int que ela representa, note que a função processa a string do final para o começo para facilitar os cálculos. No loop principal primeiramente é verificado se o caracter atual é um número (ou seja, tem que estar entre ‘0′ e ‘9′). Se for um número, a variável num é atualizada com a formula: dec * (str[len] – ‘0′). O código str[len] – ‘0′ calcula qual o valor do número atual (da mesma forma que foi feita na conversão de letras para caixa alta). Achado o número, multiplicamos ele por dec, que armazena qual a casa decimal que ele se encontra (unidade, dezena, centena, etc), e por fim o valor é somado com o número atual. Depois disso a casa decimal é atualizada (em dec *= 10).
Caso o caracter não seja um número, é verificado se a string contêm o sinal + ou – na primeira posição, caso sim, o sinal do número é atualizado de maneira adequada. Caso o caractere em questão não seja número ou sinal, a função retorna 0. O correto seria retornar algum erro, mas para não complicar o exemplo ficamos com o zero.
Na biblioteca padrão existem as funções atoi e strtol que fazem conversões de strings para números.
A conversão de int para string fica como lição de casa, uma boa leitura para se aprender mais é o artigo sobre tipos básicos do Caloni: Básico do básico: tipos.
janeiro 31, 2009 às 19:27 |
Gostei do post me envie um email para que possamos conversar.
guto . pro @ gmail . com =)
(tudo junto é claro)
fevereiro 2, 2009 às 9:59 |
Obrigado Guto! Ja lhe enviei um email.
maio 8, 2009 às 7:50 |
[...] Strings e Números [...]