|
No ultimo tutorial 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 sobre esse assunto é o artigo sobre tipos básicos do Caloni: Básico do básico: tipos.
-
08/05/2010 18:59:55 | Bruno Crivelari Sanches

Olá Adriana,
poderia dizer especificamente qual seria sua duvida? Além deste artigo temos outro sobre strings (não sei se já viu): Strings em C
-
12/10/2010 07:31:58 |189.104.5.xxx| Thuan - Comparação de strings

Olá Bruno tudo bom?
Eu quero saber como fazer a comparação de strings...pois estou fazendo um projeto, e preciso comparar senhas.
-
12/10/2010 10:37:57 | Vinícius Godoy de Mendonça

Se você estiver usando o std::string, basta compara-la com ==
Se você estive usando os char* (não recomendo), use a função strcmp.
-
12/10/2010 16:01:57 | Bruno Crivelari Sanches

Olá tudo jóia!
O artigo anterior a este mostra como fazer as comparações e explica como elas funcionam: Strings em C
Mas se for C++, sugiro o que o Vinícius comentou.
-
03/03/2011 20:51:30 |201.95.2.xxx| Pavanetti - Só uma dica

Acho que já tã meio tarde, mas... Na tabela ascii as letras maiúsculas diferem em um único bit das letras minúsculas. Pode-se fazer um xor bit-a-bit com o número 00100000 ou 0x20 ou 32.
Ao invés de:
char *toUp(char *str) {
...
str = 'A' + (str - 'a');
...
}Poderia ser:
char *toUp(char *str) {
...
str ^= 0x20;
...
}
-
09/04/2011 16:14:47 |85.246.192.xxx| mundosss - iniciando em C ( AJUDEM-ME )...

#include
int main()
{
int index = 0, contador;
char letras[5] = "Joao";
for (contador=0; contador < 1000; contador++)
{
printf("\n%c",letras[index]);
(index==3) ? index=0: ++index;
}
}
TENHO QUE AUTERAR O PROGRAMA ACIMA PARA
COMO POSSO FAZER ???
Altere o último exemplo para que ele escreva cada letra 5 vezes seguidas. Para isto, use um
'if' para testar se o contador é divisível por cinco (utilize o operador %) e só então realizar a
atualização em index.
-
09/04/2011 16:37:12 | Bruno Crivelari Sanches

Ele quer que você utilize o operador de módulo, ex:
int num = 3;
if((num % 5) == 0)
printf("diviisivel por 5" ) ;
else
printf("nao divisivel por 5 " ) ;T+
-
16/08/2011 04:16:40 |200.180.231.xxx| Paulo

duas strings que devem ser informadas pelo usuário. O programa deverá verificar se as duas strings são iguais e caso não sejam, o programa deverá mostrar primeiro a que tem menor número de caracteres e em seguida a que tem o maior número, em linhas diferentes.
me ajuda pf?
-
16/08/2011 08:36:48 | Bruno Crivelari Sanches

Qual a sua dúvida? Se for algo relativo ao artigo e especifico podemos. Se for para fazer o trabalho, não.
T+
-
30/11/2011 20:33:49 |201.48.19.xxx| Giuliane Delucca - Criptografando

Olá,
preciso criptografar um texto para numeros, onde a=0; b=1... z=25;
gostaria de saber como percorro todo o alfabeto e para cada letra, coloco um numeral. Pensei que seria assim:c=0;
for(i > 'a' ;i < 'z' ;i++){
texto=c;
c++;
}mas não tá dando certo, acho que é porque falta a função atoi. Ou então é de outro jeito.
Já agradeço pelo texto, que foi de muita ajuda.











Olá,
Preciso fazer um trabalho na faculdade,teremos que fazer uma forca alfanumerica e nao estouconseguindo trabalhar com o vetor q armazene caracteres e letras.Pode me ajudar?