Fórum Ubuntu Linux - PT
23 de Julho de 2014, 02:45 *
Olá, Visitante. Faça o login ou registre-se.
Perdeu o seu e-mail de ativação?

Login com nome de usuário, senha e duração da sessão
Notícias: Atualização no plugin de busca para Firefox e Internet Explorer.
 
   Home   Ajuda Regras Pesquisa Login Registre-se  
Anúncios
Páginas: [1]   Ir para o fundo
  Imprimir  
Autor Tópico: Caractere 'ã' influencia tamanho do retorno de strlen()???  (Lida 1774 vezes)
edjin
Usuário Ubuntu
*
Deslogado Deslogado

Mensagens: 48


Ver Perfil
« em: 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 Hein?...
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:
/*
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 » Registrado
agente100gelo
Usuário Ubuntu
*
Deslogado Deslogado

Mensagens: 3.924


@Ceará


Ver Perfil
« Responder #1 em: 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.
Registrado

Advogado e analista de sistema cearense.
Twitter: @glaydson
edjin
Usuário Ubuntu
*
Deslogado Deslogado

Mensagens: 48


Ver Perfil
« Responder #2 em: 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
Registrado
irtigor
Equipe Ubuntu
Usuário Ubuntu
*****
Deslogado Deslogado

Mensagens: 3.750


Delete, delete, delete!


Ver Perfil
« Responder #3 em: 22 de Janeiro de 2012, 16:08 »

"ç" entre outros caracteres, não são representados com apenas um byte, exemplo:
Código:
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 » Registrado
fpissarra
Usuário Ubuntu
*
Deslogado Deslogado

Mensagens: 246



Ver Perfil WWW
« Responder #4 em: 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:
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...
Registrado
edjin
Usuário Ubuntu
*
Deslogado Deslogado

Mensagens: 48


Ver Perfil
« Responder #5 em: 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 » Registrado
fpissarra
Usuário Ubuntu
*
Deslogado Deslogado

Mensagens: 246



Ver Perfil WWW
« Responder #6 em: 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!!! Piscada

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 » Registrado
edjin
Usuário Ubuntu
*
Deslogado Deslogado

Mensagens: 48


Ver Perfil
« Responder #7 em: 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.
.
Registrado
Páginas: [1]   Ir para o topo
  Imprimir  
 
Ir para:  

Powered by MySQL Powered by PHP Tema desenvolvido por FaBMak e n3t0
Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines
© 2014 Canonical Ltd. Ubuntu e Canonical são marcas registradas da Canonical Ltd.
XHTML 1.0 válido! CSS válido!