Autor Tópico: Caractere 'ã' influencia tamanho do retorno de strlen()???  (Lida 5611 vezes)

Offline edjin

  • Usuário Ubuntu
  • *
  • Mensagens: 67
    • Ver perfil
Caractere 'ã' influencia tamanho do retorno de strlen()???
« Online: 20 de Janeiro de 2012, 17:04 »
Estou com um probleminha em um exercício que pede para o usuário digitar o nome do estado (ex: São Paulo, Pernambuco, Paraíba etc.) e posteriormente retorna a sigla (ex: SP, PE, PB etc.). Mas quando digitado São Paulo, o programa só imprime a primeira letra S... alias, até imprime uma possível segunda letra para a sigla, mas pelo tamanho da string, imprime o espaço entre as duas palavras ???...
Pelos testes que fiz usando o gdb, percebi que se digitar Sao Paulo (sem o '~') imprime a saída 'SP'. A função strlen() retorna tamanhos diferentes para cada caso. O que poria ser?

Compilado com $gcc -Wall -ggdb -o programa programa.c
no ubuntu 10.10 e gcc-4.3.

Logo abaixo, o código:
 (obs.: Sei que o código está muito amador e sujo, mas foi isso que saiu...)
Código: [Selecionar]
/*
12.6.7 Escreva um programa em C que recebe via teclado o nome de um
estado (máximo 80 caracteres). Logo após a entrada do nome do estado
imprima: a sigla do estado (2 letras maiúsculas), conforme exemplos
abaixo:

Exemplo:
Estado: Rio Grande do Sul <enter>
Sigla: RS

Estado: são paulo <enter>
Sigla: SP

Estado: rio de janeiro <enter>
Sigla: RJ

Estado: <enter>
Observação: O programa encerra quando o usuário digitar apenas <enter> na entrada do nome do estado.

*/
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int main(void)
{
    char *nome=malloc(80*sizeof(char));
    int tam, i = 0;
    
    do {

fputs("\nEstado, ou [ENTER] para sair: ", stdout);
fgets(nome, 80, stdin);

if(nome[0]=='\n') break;
      
tam=strlen(nome);
tam--;

/** breackpoint gdb **/

// Primeira letra da Sigla ///
fprintf(stdout, "Sigla: %c", toupper(nome[0]));

// Laço para segunda letra da Sigla ///
for(i=tam; i>0; i--) {

// Casos 1º Amapá AP ( Incompatibilade na sequencia ) ///
if( toupper(nome[0]) == 'A' && toupper(nome[3]) == 'P' ) {
fprintf(stdout, "%c", toupper(nome[3]));
break;
}

// Casos 2º Mato Grosso MT ( Incompatibilade na sequencia ) ///
if( toupper(nome[5]) == 'G' && tam < 14 ) {
fprintf(stdout, "%c", toupper(nome[2]));
break;
}

// Casos 3º Paraiba PB ( Incompatibilade na sequencia ) ///
if(toupper(nome[5]) == 'B') {
fprintf(stdout, "%c", toupper(nome[5]));
break;
}

// Casos 4º Parana PR ( Incompatibilade na sequencia ) ///
if(toupper(nome[0]) == 'P' && toupper(nome[4]) == 'N') {
fprintf(stdout, "%c", toupper(nome[2]));
break;
}

// Casos 5º Roraima RR ( Incompatibilade na sequencia ) ///
if(toupper(nome[0]) == 'R' && toupper(nome[2]) == 'R') {
fprintf(stdout, "%c", toupper(nome[2]));
break;
}

// Casos 6º São Paulo SP ( Incompatibilade na sequencia ) ///
if(toupper(nome[0]) == 'S' && toupper(nome[4]) == 'P') {

fprintf(stdout, "%c", toupper(nome[4]));
break;
}

// Para segunda letra das Siglas compostas (dois ou mais nomes) ///
if(nome[i] == ' ' && tam>=9) {
fprintf(stdout, "%c", toupper(nome[i+1]));
break;
}

// Para segunda letra das siglas simples (Somente um nome) ///
if(nome[i]!=' ' && tam<=10) {
fprintf(stdout, "%c", toupper(nome[1]));
break;
}
}
} while(1);
      
    free(nome);
    return 0;
}

« Última modificação: 20 de Janeiro de 2012, 17:18 por edjin »

Offline agente100gelo

  • Administrador
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.369
  • @Ceará
    • Ver perfil
Re: Caractere 'ã' influencia tamanho do retorno de strlen()???
« Resposta #1 Online: 20 de Janeiro de 2012, 17:20 »
Nunca me arrisquei em C mas acho que o caminho seria:

1. Crie uma array associativa. No PHP seria:

$estado["ceará"] = "CE";
$estado["São Paulo"] = "SP";

2. Capture a informação.

3. Pela associação da array retorne a sigla.
Advogado e analista de sistema cearense.
Twitter: @glaydson

Offline edjin

  • Usuário Ubuntu
  • *
  • Mensagens: 67
    • Ver perfil
Re: Caractere 'ã' influencia tamanho do retorno de strlen()???
« Resposta #2 Online: 20 de Janeiro de 2012, 17:38 »
Olá agente100gelo, antes de mais nada agradecendo seu interesse pelo caso... Então, assim resolveria o caso sem problema ,  mas teria que comparar com duas strings, uma com 'ã' e outra com 'a', sem contar as diversas possibilidades dos outros estados, (achei mais fácil fazer o trabalho só com a string digitada) e mesmo assim continuaria a duvida com relação a strlen(). Mas muito obrigado pela resposta. []s

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: Caractere 'ã' influencia tamanho do retorno de strlen()???
« Resposta #3 Online: 22 de Janeiro de 2012, 16:08 »
"ç" entre outros caracteres, não são representados com apenas um byte, exemplo:
Código: [Selecionar]
fprintf(stdout, "Tamanho: %d", strlen("→"));
Vai retornar 3. Sendo direto, você está olhando a posição errada. Isso deve ajudar:
http://www.cl.cam.ac.uk/~mgk25/unicode.html#mod
« Última modificação: 22 de Janeiro de 2012, 17:55 por irtigor »

Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Caractere 'ã' influencia tamanho do retorno de strlen()???
« Resposta #4 Online: 23 de Janeiro de 2012, 14:18 »
edjin, o irtigor está correto em dizer:

"ç" entre outros caracteres, não são representados com apenas um byte, exemplo:
Código: [Selecionar]
fprintf(stdout, "Tamanho: %d", strlen("→"));
Vai retornar 3. Sendo direto, você está olhando a posição errada. Isso deve ajudar:
http://www.cl.cam.ac.uk/~mgk25/unicode.html#mod

O motivo é o a forma com que os caracteres são codificados. As diversas distribuições Linux tendem a usar, por default, o conjunto de caracteres conhecido com UTF-8, que é um MBCS (Multi Byte Character Set), ao contrário do Windows, onde a codificação WINDOWS-1251 ou WINDOWS-1252 é usada (e é SBCS, Single Byte Character Set).

Uma possível solução (não tão garantida assim) é usar o tipo wchar_t e a biblioteca iconv para converter o charset UTF-8 para UTF-16 ou WCHAR_T. Nesses charsets cada caracter têm 16 bits de tamanho e a concatenação de multiplos "words" para compor um caracter é rara (mas, existe, no caso do UTF-16!).

Dê uma olhada neste artigo que escrevi ano passado, num blog que compartilho com um amigo. Espero que ajude...

Offline edjin

  • Usuário Ubuntu
  • *
  • Mensagens: 67
    • Ver perfil
Re: Caractere 'ã' influencia tamanho do retorno de strlen()???
« Resposta #5 Online: 27 de Janeiro de 2012, 13:44 »
Estou estudando (google tradutor rsss) pelo link que o amigo irtigor indicou, mas com o artigo (por sinal otimo artigo) do guru fpissarra acredito que vai ser mais facil (pt_BR). Ah, e pra quem tiver a mesma duvida, leiam o artigo, pois e muito esclarecedor.
Assim que resolver a pendenga, coloco um sinal de [resolvido]...
Abracos.
« Última modificação: 31 de Janeiro de 2012, 16:16 por edjin »

Offline fpissarra

  • Usuário Ubuntu
  • *
  • Mensagens: 246
    • Ver perfil
    • Lost in the e-Jungle
Re: Caractere 'ã' influencia tamanho do retorno de strlen()???
« Resposta #6 Online: 27 de Janeiro de 2012, 22:02 »
Estou estudando (google tradutor rsss) pelo link que o amigo irtigor indicou, mas com o artigo (por sinal OTIMO ARTIGO) do guru fpissarra acredito que vai ser mais facil (pt_BR). Ah, e pra quem tiver a mesma duvida, leiam o artigo, pois e muito esclarecedor.
Assim que resolver a pendenga, coloco um sinal de [RESOLVIDO]...
Abracos.

Thanks a lot!!! ;)

Infelizmente, no meu antigo blog (hoje desativado) eu tinha mais 2 artigos interessantes sobre UTF-8 e Unicode. Recomendo que você baixe a especificação aqui e dê uma lida. Unicode (UTF-8 e outros formatos) tem recursos como composição de caracteres (tipo: A e ^ podem ser mesclados e aparecer como  - por ai!)...

[]s
Fred
« Última modificação: 27 de Janeiro de 2012, 22:08 por fpissarra »

Offline edjin

  • Usuário Ubuntu
  • *
  • Mensagens: 67
    • Ver perfil
Re: Caractere 'ã' influencia tamanho do retorno de strlen()???
« Resposta #7 Online: 31 de Janeiro de 2012, 16:36 »
É muito bom poder contar com a ajuda de pessoas (fpissarra, agete100gelo, irtigor, tota entre outros...) que acreditam que somente pelo conhecimento podemos melhorar o mundo a nossa volta. Ahhh ve se ativa o blog de novo, boa informação tem que ser difundida, mesmo que os meios sejam difíceis.

Aqui a cabeça ta pegando fogo... -->> To ansioso pelo [resolvido] lá em cima.
Abraços a todos.
.