Converter texto minúsculo para maiúsculo no GCC [RESOLVIDO]

1. Converter texto minúsculo para maiúsculo no GCC [RESOLVIDO]

Edivaldo
kito.eag

(usa Ubuntu)

Enviado em 19/09/2016 - 19:17h

Olá,

Estava procurando um maneira de converter texto minúsculo para maiúsculo usando o compilador GCC. Encontrei alguns mas não convertiam caracteres como "ç" ou acentuados como "é", "á", "à", etc... Como estou usando Ubuntu 16.04, percebi que estes caracteres são compostos de dois bytes.
Por exemplo, o "ç" é formado pelos números decimais "-61" e "-89" e o c-cedilha maiúsculo corresponde a "-61" e "-121".
Na tabela ascii, o valor do caractere "a" é "97". Porém, se a vogal é acentuada, percebi que ela também se torna composta de dois bytes: "á" = "-61" e "-95" e , (Á) maiúsculo, tem os valores: "-61" e "-127". Para mudar "á" para "Á" bastou subtrair o "-32" do segundo byte.

Segue abaixo o código:


#include <stdio.h>

void conv_maiuscula(char* s){
int i;
for (i=0; s[i] != '\0'; i++){
//Trata caracteres "normais"
if(s[i] >= 'a' && s[i] <= 'z'){ s[i] -= 32;}

//Trata caracteres "especiais"
if(s[i] == -61){
i++;
s[i] -= 32;
}
}
}

main()
{
char c[20];
system("clear");
while(1)
{
printf("\nDigite: ");
scanf("%[^\n]",c); // %[^\n] serve para ler espaços em branco.

fflush(stdin); //Limpa buffer do teclado (no Linux)
__fpurge(stdin);

system("clear"); //Limpa tela

printf("Texto digitado: %s \n", c);

conv_maiuscula(c); //Chama função para converter

printf("\nMaiúsculo: %s \n", c);
}
return 0;
}


Se alguém tiver outra maneira de fazer isso favor compartilhar...



  


2. Re: Converter texto minúsculo para maiúsculo no GCC

Paulo
paulo1205

(usa Ubuntu)

Enviado em 19/09/2016 - 20:24h

Antes de falar da pergunta principal, permita-me sugerir que não use nem “fflush(stdin)” nem tampouco “fpurge(stdin)”. Nenhuma das duas funções é portável para outros sistemas. Um jeito de fazer o que você quer é suprimir essas duas funções, e trocar aquela chamada a scanf() pelo seguinte.
scanf("%19[^\n]%*1[\n]", c)  /* Limita o tamanho máximo para caber no array, e ainda retira a quebra de linha do buffer. */ 

Melhor ainda se você testar eventuais situações de erro. Leia a documentação de scanf().

Agora à dúvida original...

Conjuntos de caracteres estendidos e os diversos meios de representá-los são temas bastante complexos. Mesmo na sua própria máquina, se você trocar o valor de uma simples variável de ambiente, tudo o que você viu e relatou aqui pode mudar radicalmente.

O que você observou parece indicar que você está usando um conjunto de caracteres Unicode, codificado através da representação UTF-8. UTF-8 utiliza um comprimento de bytes variável para representar diferentes faixas de caracteres: um byte para caracteres de 0 a 127, dois bytes para 128 a 2047, três bytes, para 2048 a 65535, quatro bytes para 65536 até 1114111, que é o limite superior atualmente usado pelo Unicode.

Uma forma simplória (e padronizada pelo C) de fazer o que você quer é trabalhar com as funções de conversão entre strings multibyte (array de chars) e wide characters (wchar_t) ou strings de wide characters.

Para isso, a primeira coisa a fazer a instruir o programa a usar uma representação de locales adequada (por padrão, o sistema usa a locale defaut do C, mesmo que o sistema esteja configurada com outra locale ). Depois disso, você pode usar mbstowcs() e wcstombs(). Uma vez de posse dos wide characters, você pode usar as funções de <wctype.h> (análogas para wchar_t das funções de <ctype.h>, usada sobre caracteres comuns).


3. Re: Converter texto minúsculo para maiúsculo no GCC [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 20/09/2016 - 00:56h

Pensando bem, uma forma mais direta é trocar o tipo de dados, para trabalhar diretamente com uma string de wchar_t.

#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>

int main(void){
setlocale(LC_ALL, ""); /* Define que o C deve usar a locale do sistema. */
wchar_t str[20]={0};
printf("Digite seu nome: ");
if(scanf("%19l[^\n]%*1[\n]", str)!=1){
fprintf(stderr, "Erro de leitura.\n");
return 1;
}
size_t len=wcslen(str);
for(size_t n=0; n<len; n++)
str[n]=towupper(str[n]);
printf("Seu nome em maiúsculas: %ls\n", str);
return 0;
}



4. Re: Converter texto minúsculo para maiúsculo no GCC [RESOLVIDO]

Edivaldo
kito.eag

(usa Ubuntu)

Enviado em 20/09/2016 - 16:55h

Cara, era exatamente isso que eu estava procurando. Estou iniciando em C e procurei muito por isto. Cheguei até encontrar algo parecido mas não conseguia fazer funcionar. Testei este código que você postou e funcionou perfeitamente.
Gostaria de saber se ele também funcionaria em outras distribuições Linux e também no gcc para Windows.
Mas era isso mesmo. Muito obrigado pela ajuda. Valeu!


5. Re: Converter texto minúsculo para maiúsculo no GCC [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 21/09/2016 - 13:41h

Não esqueça de marcar o tópico como resolvido e, se possível, indicar a melhor resposta.


6. Re: Converter texto minúsculo para maiúsculo no GCC

Edivaldo
kito.eag

(usa Ubuntu)

Enviado em 22/09/2016 - 16:42h

paulo1205 escreveu:

Pensando bem, uma forma mais direta é trocar o tipo de dados, para trabalhar diretamente com uma string de wchar_t.

#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>

int main(void){
setlocale(LC_ALL, ""); /* Define que o C deve usar a locale do sistema. */
wchar_t str[20]={0};
printf("Digite seu nome: ");
if(scanf("%19l[^\n]%*1[\n]", str)!=1){
fprintf(stderr, "Erro de leitura.\n");
return 1;
}
size_t len=wcslen(str);
for(size_t n=0; n<len; n++)
str[n]=towupper(str[n]);
printf("Seu nome em maiúsculas: %ls\n", str);
return 0;
}




Surgiu um problema. Quando migrei para o wchar_t, percebi que algumas funções que funcionavam bem com char mas agora dão erro com o wchar_t. São elas:
fgets
strstr
sscanf
strcmp

Existe funções alternativas a estas para usar com wchar_t?



7. Re: Converter texto minúsculo para maiúsculo no GCC [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 22/09/2016 - 19:10h

kito.eag escreveu:

Surgiu um problema. Quando migrei para o wchar_t, percebi que algumas funções que funcionavam bem com char mas agora dão erro com o wchar_t. São elas:
fgets
strstr
sscanf
strcmp


Sim. Dê uma olhada em http://man7.org/linux/man-pages/man0/wchar.h.0p.html.


8. Re: Converter texto minúsculo para maiúsculo no GCC [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 23/09/2016 - 09:15h

Patrick03 escreveu:

Paulo? Tem como eu mandar algum e-mail para ti ou algo do tipo?
Tenho um "código"/projeto que queria, caso não fosse um incomôdo, que tu desse uma olha e disse o que eu deveria melhorar, deletar ou adicionar.


Prezado Patrick,

Eu prefiro compartilhar conhecimento de modo público, de forma que possa ser útil não apenas para você, mas também para outros com dúvidas semelhantes.

Atendimento particular vira consultoria. Os profissionais que vivem de consultoria ficaria muito chateados com alguém que fizesse de graça os serviços que eles vendem como seu ganha-pão.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts