Ir ao conteúdo

Posts recomendados

Postado

Eu tenho a funcao de remover acentos e transformar em maiúsculo abaixo:
 

//bibliotecas usadas
#include <stdio.h>
#include <string.h>



//tratar string
void tratarString(char palavra[]) {
  unsigned int i, k, x = 0;
  char comAcentos[] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç";
  char semAcentos[] = "AAAAAAaaaaaEEEEeeeeIIIIiiiiOOOOOoooooUUUuuuuCc";
  //Removendo acentos
  for (k = 0; k < strlen(palavra); k++) {

  for (i = 0; i < strlen(comAcentos); i++) {
  if (palavra[k] == comAcentos[i]) {
  palavra[k] = semAcentos[i];
  }
  }
  }
  //Transformando em maiúsculo
  while (palavra[x]) {
  palavra[x] = toupper(palavra[x]);
  x++;
  }
}



//Quando aplico ela no main, e passo a variavel já com o valor  ela aceita

int main(void) {

    char entrada[100] = "Hugo Jóse";
    //scanf("%s",entrada);

    //receberInputUsuario(entrada,100);

    tratarString(entrada);

    printf("%s",entrada);

    return 0;
}

//saida desse algoritmo é : HUGO JOSE

 


 //Quando aplico em um fgets:
  // ele so le as letras que não tem acento, as que tem ele deixa da forma que esta

 

int main(void) {

    char entrada[100];;
    setbuf(stdin,NULL);

    scanf("%s",entrada);

    tratarString(entrada);

    printf("%s",entrada);

    return 0;
}

//saida desse algoritmo se for escrito algo como o exemplo anterior sai "HUGO"



 
Quando eu aplico fgets eu não consigo converter “çãõ” para “CAO” pois a saida que ele da e “çãõ” e não a que eu esperava que é “CAO”.
 
como posso corrigir esse erro?

  • Curtir 1
Postado
8 horas atrás, HUGO_dev_ze disse:

//Quando aplico em um fgets:
  // ele so le as letras que não tem acento, as que tem ele deixa da forma que esta

 

Só que não está usando fgets()

 

int main(void)
{
    char entrada[100];;
    setbuf(stdin,NULL);
    scanf("%s",entrada);
    tratarString(entrada);
    printf("%s",entrada);
    return 0;
}
//saida desse algoritmo se for escrito algo como o exemplo anterior sai "HUGO"

 

Pois é: note o seu comentário... scanf() não é fgets() e para no primeiro branco, TAB ou newline. Nunca vai ler o resto, ao menos não com esse especificador. E não tem acentos em HUGO então não vai saber se deu certo.

 

Nunca use setbuf() na entrada. Não vai te servir de nada. Essa função não é para isso. Apenas escreva seu programa de modo a consumir os dados corretamente.

 

Use um vetor com strings de teste. É mais produtivo.

 

Seu código está muito confuso e lerdo por ter nada menos que 2 for e um while. E dezenas e dezenas de chamadas a strlen() e toupper() quando não precisava de nenhuma. E a setbuf() na entrada

 

  • Curtir 1
Postado

O normal para esse tipo de programa é escrever um programa para gerar uma tabela em C e depois incluir no programa definitivo, que aí tem um loop só, que não testa nada e apenas aplica a tabela. É o mais rápido. Muito mais rápido.

 

Mas de todo modo usando o convencional precisa de apenas mais duas variáveis para ter o que imagino que seja a solução mínima, e dois loops, algo assim
 

char* tratar_string(char* palavra)
{
    const char antes[] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz";
    const char depois[] = "AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCC"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    char* letra = palavra;
    while (*letra != 0) {
        char* alvo = (char*) antes;  // as letras
        while (*alvo != 0)
        {   // compara com todas
            if (*alvo != *letra)
            {   // essa não eh
                alvo += 1;
                continue;
            }
            *letra = *(depois + (alvo - antes)); // troca
        }
        letra += 1; // avanca na palavra
    }
    return palavra; // retorna o texto alterado
};

 

A diferença

 

Não é preciso usar dois loops para a mesma entrada. É mais simples colocar as letras junto e fazer implicitamente a conversão para maiúscula. E não precisa de strlen() ou toupper(). Deve ser dezenas de vezes mais rápido.

 

E é esperto retornar um ponteiro para a própria string. Todas essas funções de string.h fazem isso, como fgets() e strcat().

 

Um teste

 

Esse programa permite digitar umas strings de teste direto no vetor e passa todas pela rotina, usando o ponteiro retornado para simplificar as coisas:

 

int main(void)
{
    char* entrada[] =
    {
        "Hugo Jósé",
        "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz",
        "Clube do Hardware",
        "Ação ou Inércia?",
        "abcdefghijklmnopqrstuvwxyz"};

    // muda o locale para mostrar os simbolos "certos"
    printf("locale original: %s\n", setlocale(LC_ALL, NULL));
    char* local = setlocale(LC_ALL, "pt-BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);

    // N testes, assim pode editar o vetor e criar outros
    size_t N = sizeof(entrada) / sizeof(char*);
    printf("\n%zd testes", N);

    // faz os testes, claro
    for (size_t t = 0; t < N; t += 1)
    { 
        printf("\
\n\
\n\
    teste %zd de %zd:\n\
    antes:  \"%s\" (%zd)\n",
            1+t,
            N, entrada[t], strlen(entrada[t]));
        printf(
            "\
    depois: \"%s\" (%zd)\n",
            tratar_string(entrada[t]), strlen(entrada[t]));
    }
    return 0;
}

 

É só um for com um printf() dentro.

 

A saída

 

5 testes

    teste 1 de 5:
    antes:  "Hugo Jósé" (9)
    depois: "HUGO JOSE" (9)


    teste 2 de 5:
    antes:  "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇçabcdefghijklmnopqrstuvwxyz" (72)
    depois: "AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCCABCDEFGHIJKLMNOPQRSTUVWXYZ" (72)


    teste 3 de 5:
    antes:  "Clube do Hardware" (17)
    depois: "Clube do Hardware" (17)


    teste 4 de 5:
    antes:  "Ação ou Inércia?" (16)
    depois: "ACAO OU INERCIA?" (16)


    teste 5 de 5:
    antes:  "abcdefghijklmnopqrstuvwxyz" (26)
    depois: "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (26)

 

O programa todo

 

#include <ctype.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>

char* tratar_string(char*);

int main(void)
{
    char* entrada[] =
    {
        "Hugo Jósé",
        "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz",
        "Clube do Hardware",
        "Ação ou Inércia?",
        "abcdefghijklmnopqrstuvwxyz"};

    // muda o locale para mostrar os simbolos "certos"
    printf("locale original: %s\n", setlocale(LC_ALL, NULL));
    char* local = setlocale(LC_ALL, "pt-BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);

    // N testes, assim pode editar o vetor e criar outros
    size_t N = sizeof(entrada) / sizeof(char*);
    printf("\n%zd testes", N);

    // faz os testes, claro
    for (size_t t = 0; t < N; t += 1)
    { 
        printf("\
\n\
\n\
    teste %zd de %zd:\n\
    antes:  \"%s\" (%zd)\n",
            1+t,
            N, entrada[t], strlen(entrada[t]));
        printf(
            "\
    depois: \"%s\" (%zd)\n",
            tratar_string(entrada[t]), strlen(entrada[t]));
    }
    return 0;
}

char* tratar_string(char* palavra)
{
    const char antes[] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz";
    const char depois[] = "AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCC"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    char* letra = palavra;
    while (*letra != 0) {
        char* alvo = (char*) antes;  // as letras
        while (*alvo != 0)
        {   // compara com todas
            if (*alvo != *letra)
            {   // essa não eh
                alvo += 1;
                continue;
            }
            *letra = *(depois + (alvo - antes)); // troca
        }
        letra += 1; // avanca na palavra
    }
    return palavra; // retorna o texto alterado
};

 

  • Curtir 1
  • Obrigado 1
Postado

@arfneto     usando o codeblocks , esse código compilou e retornou -1 significando que setlocale encontrou NULL , e não mostrou as letras iguais ao que você postou ,  e no visual studio não compilou ,  e modificando o vetor ponteiro para string compilou mas não mostrou também ,  qual seria o motivo ? 

#define _CRT_SECURE_NO_WARNINGS
#include <ctype.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>

char* tratar_string(char*);

int main(void)
{
    char entrada[15][100] =
    {
        "Hugo Jósé",
        "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        /*"abcdefghijklmnopqrstuvwxyz",
        "Clube do Hardware",
        "Ação ou Inércia?",
        "abcdefghijklmnopqrstuvwxyz" */
    };

    printf("Entrada zero -> %s\n", entrada[1]);
    // muda o locale para mostrar os simbolos "certos"
    printf("locale original: %s\n", setlocale(LC_ALL, NULL));
    char* local = setlocale(LC_ALL, "pt-BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);

    // N testes, assim pode editar o vetor e criar outros
    size_t N = sizeof(entrada) / sizeof(char*);
    printf("\n%zd testes", N);

    // faz os testes, claro
    for (size_t t = 0; t < N; t += 1)
    {
        printf("\
\n\
\n\
    teste %zd de %zd:\n\
    antes:  \"%s\" (%zd)\n",
            1 + t,
            N, entrada[t], strlen(entrada[t]));
        printf(
            "\
    depois: \"%s\" (%zd)\n",
            tratar_string(entrada[t]), strlen(entrada[t]));
    }
    return 0;
}

char* tratar_string(char* palavra)
{
    const char antes[] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz";
    const char depois[] = "AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCC"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    char* letra = palavra;
    while (*letra != 0) {
        char* alvo = (char*)antes;  // as letras
        while (*alvo != 0)
        {   // compara com todas
            if (*alvo != *letra)
            {   // essa não eh
                alvo += 1;
                continue;
            }
            *letra = *(depois + (alvo - antes)); // troca
        }
        letra += 1; // avanca na palavra
    }
    return palavra; // retorna o texto alterado
};

 

Postado

 

1 hora atrás, devair1010 disse:

  qual seria o motivo ? 

 

Não sei ao certo.

 

1 hora atrás, devair1010 disse:

e no visual studio não compilou

 

e porque não postou os erros? Não consigo imaginar o que seu compilador pode ter dito. Não sei as opções que usa nem nada. Em que linha deu erro? que erro?

 

que compilador usa com esse Code::Blocks? que versão? Sua máquina roda Windows em português? Tem esse locale "pt-BR" --- é o padrão...

 

Qual a razão de mudar isso?

 

   char entrada[15][100] // ...

 

Está errado. Porque mudar isso? A única maneira que me ocorre de melhorar essa solução é o que eu expliquei no primeiro parágrafo.

 

Você deve ler bem o código que está tentando mudar... E entender a diferença entre char*[]  e char[][100]

 

Sabe quanto vai dar isso no seu caso:

 

    size_t N = sizeof(entrada) / sizeof(char*);

 

Vai dar 375 (32bits) . Ou 187 (64bits). E seu programa vai cancelar.

 

E porque eu escrevi essa linha? 

 

Porque assim você pode editar o vetor entrada sem mexer no programa, para fazer mais ou menos testes. Veja o comentário:

 

    // N testes, assim pode editar o vetor e criar outros
    size_t N = sizeof(entrada) / sizeof(char*);

 

Pois é... Acho que não leu. :) 

 

Não consigo imaginar uma vantagem de mudar isso, mas se mudou então faça o resto e escreva assim

 

int main(void)
{
    char entrada[][100] =
    {
        [0] = "Hugo Jósé",
        [1] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
    };
    size_t N = 2;

    printf("Entrada zero -> %s\n", entrada[0]);
    // muda o locale para mostrar os simbolos "certos"
    printf("locale original: %s\n", setlocale(LC_ALL, NULL));
    char* local = setlocale(LC_ALL, "pt-BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);
//...

 

E aí vai ver

 

Entrada zero -> Hugo J¾sÚ
locale original: C
locale alterado para "pt_BR"

2 testes

    teste 1 de 2:
    antes:  "Hugo Jósé" (9)
    depois: "HUGO JOSE" (9)


    teste 2 de 2:
    antes:  "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç" (46)
    depois: "AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCC" (46)

 

Porque escreveu

 

    printf("Entrada zero -> %s\n", entrada[1]);

 

???

 

1 hora atrás, devair1010 disse:

esse código compilou e retornou -1 significando que setlocale encontrou NULL

 

Sobre o locale dar erro:

 

C:\Users\toninho>locale -a | grep -i pt
pt_BR
pt_BR.utf8
pt_PT
pt_PT.utf8
pt_PT@euro

 

Em geral o locale é o código internacional do idioma com duas letras minúsculas e depois o código do país com duas maiúsculas, como em pt_BR e en_US.

 

Só que no código está com hífen. Eu digitei assim. E na máquina que estou usando agora, apesar de sequer existir esse locale com hífen, o Windows aceita e de fato muda porque depois aparece assim. Eu nunca tinha pensado nisso... Nunca usei isso em Windows exceto aqui :) e não ia ver nunca.

 

locale original: C
locale alterado para "pt-BR"

 

O seu programa, alterado

 

#define _CRT_SECURE_NO_WARNINGS
#include <ctype.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>

char* tratar_string(char*);

int main(void)
{
    char entrada[15][100] =
    {
        [0] = "Hugo Jósé",
        [1] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
    };
    size_t N = 2;

    printf("Entrada zero -> %s\n", entrada[0]);
    // muda o locale para mostrar os simbolos "certos"
    printf("locale original: %s\n", setlocale(LC_ALL, NULL));
    char* local = setlocale(LC_ALL, "pt_BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);

    printf("\n%zd testes", N);

    // faz os testes, claro
    for (size_t t = 0; t < N; t += 1)
    {
        printf(
            "\
\n\
\n\
    teste %zd de %zd:\n\
    antes:  \"%s\" (%zd)\n",
            1 + t, N, entrada[t], strlen(entrada[t]));
        printf(
            "\
    depois: \"%s\" (%zd)\n",
            tratar_string(entrada[t]), strlen(entrada[t]));
    }
    return 0;
}

char* tratar_string(char* palavra)
{
    const char antes[] =
        "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz";
    const char depois[] =
        "AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCC"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    char* letra = palavra;
    while (*letra != 0)
    {
        char* alvo = (char*)antes;  // as letras
        while (*alvo != 0)
        {  // compara com todas
            if (*alvo != *letra)
            {  // essa não eh
                alvo += 1;
                continue;
            }
            *letra = *(depois + (alvo - antes));  // troca
        }
        letra += 1;  // avanca na palavra
    }
    return palavra;  // retorna o texto alterado
};

 

  • Obrigado 1
Postado

 

13 horas atrás, arfneto disse:

Está errado. Porque mudar isso? A única maneira que me ocorre de melhorar essa solução é o que eu expliquei no primeiro parágrafo.

 

Seria isso, sobre a melhor maneira de fazer:

 

17 horas atrás, arfneto disse:

O normal para esse tipo de programa é escrever um programa para gerar uma tabela em C e depois incluir no programa definitivo, que aí tem um loop só, que não testa nada e apenas aplica a tabela. É o mais rápido. Muito mais rápido.

 

15 horas atrás, devair1010 disse:

e no visual studio não compilou

 

Mas qual foi o erro no Visual Studio?

 

EXEMPLO

 

@devair1010 Acho que eu resumi muito a razão de você  ter "quebrado" o programa ao mudar a declaração do vetor. É um problema comum mesmo para profissionais então vou deixar um exemplo em C um pouco mais completo

 

A saída do programa

 

locale alterado para "pt_BR"
sizeof(): v1 = 500 v2 = 200 v3 = 8 v4 = 8 char* = 4

   v1[1] -> ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç
   v2[1] -> Húgô Jósé
   v3[1] -> ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç
  *v4[1] -> ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç

 

Veja que compilando em 32 bits o ponteiro para char tem 4 bytes. E a conta que o programa original fazia em

 

    size_t N = sizeof(entrada) / sizeof(char*);

 

Vai dar 2 para v3 e v4. E em 64bits também vai dar 2. Então você pode editar o vetor para incluir ou excluir testes e o valor de N sempre vai estar certinho. Se usa isso para testes com valores que viriam de arquivo ou do teclado durante testes por essa óbvia razão: não precisa alterar nada para mudar os testes.

 

Veja o código abaixo e vai entender que se mudar a declaração tem que colocar o valor de N por sua conta:

 

#include <locale.h>
#include <stdio.h>
int main(void)
{
    char v1[5][100] = {
        "Húgô Jósé", "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"};

    char v2[][100] = {
        [1] = "Húgô Jósé",
        [0] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
    };
    
    char* v3[] = {
        "Húgô Jósé",
        "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç",
    };

    char** v4[] = { &v3[0], &v3[1] };

    char* local = setlocale(LC_ALL, "pt_BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);
    printf("sizeof(): v1 = %zd v2 = %zd v3 = %zd v4 = %zd char* = %zd\n\n",
        sizeof(v1), sizeof(v2), sizeof(v3), sizeof(v4), sizeof(char*));
    printf(
        "\
   v1[1] -> %s\n\
   v2[1] -> %s\n\
   v3[1] -> %s\n\
  *v4[1] -> %s\n",
        v1[1], v2[1], v3[1], *v4[1] );
    return 0;
}

 

Os valores: v1 v2 v3 e v4 na memória

 

Veja isso na prática: 

 

v1 é char[5][100] e tem o tamanho fixo: lá em 0x00DBFB34 começam os 500 bytes e ponto final.

v2 é char[2][100] porque o compilador contou quantos tinha no programa

v3 é char*[2] então só tem os ponteiros em 0xD9FA54 e os valores aparecem depois em outro lugar

v4 é char** e é bem parecido, mas tem que ser construído na hora com ponteiros válidos para cada posição. 

 

Note que em v4 a ordem está invertida, de propósito. E em v2 as declarações estão fora de ordem

 

image.png.8e35d26b89bb869f716852ea4f99f6a7.png

 

Entendeu a diferença que faz a declaração e o modelo de memória, @devair1010?

 

  • Obrigado 1
Postado

@devair1010 ainda com esse lance de vetores ponteiros e strings 

 

Em C e C++ é comum criar um bloco como o sistema cria para os argumentos em main

 

    int main(int argc, char** argv);

 

E aí tem um vetor mesmo de ponteiros para as strings na memória, e os ponteiros ficam em sequencia na memória

 

Algo assim no programa acima:

 


    char** v5 = (char**)malloc(2 * sizeof(char*));
    char* uma_string = "Forum Clube do Hardware";
    v5[0] = v3[0];
    v5[1] = uma_string;

 

E nesse caso na memória  a partir do endereço de v5 vem os ponteiros para as strings... Veja o conteúdo da memória a partir de 0xB46238 abaixo:

 

image.png.093016b83724b3e4c997440b36123757.png

 

EXEMPLO com os 5 vetores

 

Umas linhas a mais que o anterior. Note o tamanho de v5: 4 bytes.

 

locale alterado para "pt_BR"
sizeof(): v1 = 500 v2 = 200 v3 = 8 v4 = 8 v5 = 4 char* = 4

   v1[1] -> ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç
   v2[1] -> Húgô Jósé
   v3[1] -> ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç
  *v4[1] -> Húgô Jósé
   v5[1] -> Forum Clube do Hardware

 

#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    char v1[5][100] = {
        "Húgô Jósé", "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"};

    char v2[][100] = {
        [1] = "Húgô Jósé",
        [0] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
    };
    
    char* v3[] = {
        "Húgô Jósé",
        "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç",
    };

    char** v4[] = { &v3[1], &v3[0] };

    char** v5 = (char**)malloc(2 * sizeof(char*));
    char* uma_string = "Forum Clube do Hardware";
    v5[0] = v3[0];
    v5[1] = uma_string;

    char* local = setlocale(LC_ALL, "pt_BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);
    printf("sizeof(): v1 = %zd v2 = %zd v3 = %zd v4 = %zd v5 = %zd char* = %zd\n\n",
        sizeof(v1), sizeof(v2), sizeof(v3),
        sizeof(v4), sizeof(v5),
        sizeof(char*));
    printf(
        "\
   v1[1] -> %s\n\
   v2[1] -> %s\n\
   v3[1] -> %s\n\
  *v4[1] -> %s\n\
   v5[1] -> %s\n ",
       v1[1], v2[1], v3[1], *v4[1], v5[1]);
    return 0;
}

 

  • Curtir 1
Postado

@arfneto       nesse programa original

/**
    O programa todo
**/

#include <ctype.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>

char* tratar_string(char*);

int main(void)
{
    char* entrada[] =
    {
        "Hugo Jósé",
        "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz",
        "Clube do Hardware",
        "Ação ou Inércia?",
        "abcdefghijklmnopqrstuvwxyz"};

    // muda o locale para mostrar os simbolos "certos"
    printf("locale original: %s\n", setlocale(LC_ALL, NULL));
    char* local = setlocale(LC_ALL, "pt-BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);

    // N testes, assim pode editar o vetor e criar outros
    size_t N = sizeof(entrada) / sizeof(char*);
    printf("\n%zd testes", N);

    // faz os testes, claro
    for (size_t t = 0; t < N; t += 1)
    { 
        printf("\
\n\
\n\
    teste %zd de %zd:\n\
    antes:  \"%s\" (%zd)\n",
            1+t,
            N, entrada[t], strlen(entrada[t]));
        printf(
            "\
    depois: \"%s\" (%zd)\n",
            tratar_string(entrada[t]), strlen(entrada[t]));
    }
    return 0;
}

char* tratar_string(char* palavra)
{
    const char antes[] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz";
    const char depois[] = "AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCC"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    char* letra = palavra;
    while (*letra != 0) {
        char* alvo = (char*) antes;  // as letras
        while (*alvo != 0)
        {   // compara com todas
            if (*alvo != *letra)
            {   // essa não eh
                alvo += 1;
                continue;
            }
            *letra = *(depois + (alvo - antes)); // troca
        }
        letra += 1; // avanca na palavra
    }
    return palavra; // retorna o texto alterado
};

deu esses erros , 
 

1309898741_conschar.jpg.9e4d05bda956f7fb161c5bfb5a54b61d.jpg

 

e coloquei essa img pois no editor não dá para copiar e colar as msg de erros
 

Em 19/11/2021 às 22:37, arfneto disse:

Qual a razão de mudar isso?

 

   char entrada[15][100] // ...

 

usando a variável  " entrada " 

char* entrada[] =

como ponteiro , não compilava no v studio , e depois dessa mudança compilou ,

 

Em 19/11/2021 às 22:37, arfneto disse:

Sabe quanto vai dar isso no seu caso:

 

    size_t N = sizeof(entrada) / sizeof(char*);

 

Vai dar 375 (32bits) . Ou 187 (64bits). E seu programa vai cancelar.

 


por que vai cancelar  ?   o limite de size_t é 256 ?   ,    entendi Que entrada[15][100]  será 15 vezes de 100  , igual a 1500 e dividido por 4 , que  é o tamanho de um char será igual a 375 , mas imaginei que fosse bytes , e não bits , . .  . !

 

Em 19/11/2021 às 22:37, arfneto disse:

Porque escreveu

 

    printf("Entrada zero -> %s\n", entrada[1]);

 

???


testando o que está na matriz entrada , pois com números não precisa desses colchetes [0] "..."

e no codeblocks  , que creio que esteja usando o compilador GNU GCC e também o minGW , 

1006988505_settingscb.thumb.jpg.1aa18b6fdaa9eeb625e42c60445b26da.jpg

 

compilou de boa , e logo depois de mudar a locale saiu e retornou -1 

 

1158849258_localeoriginal.jpg.336f5540db8979b02f0b5f8cebc12891.jpg

 

e infelizmente esse outro

 

13 horas atrás, arfneto disse:
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    char v1[5][100] = {
        "Húgô Jósé", "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"};

    char v2[][100] = {
        [1] = "Húgô Jósé",
        [0] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
    };
    
    char* v3[] = {
        "Húgô Jósé",
        "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç",
    };

    char** v4[] = { &v3[1], &v3[0] };

    char** v5 = (char**)malloc(2 * sizeof(char*));
    char* uma_string = "Forum Clube do Hardware";
    v5[0] = v3[0];
    v5[1] = uma_string;

    char* local = setlocale(LC_ALL, "pt_BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);
    printf("sizeof(): v1 = %zd v2 = %zd v3 = %zd v4 = %zd v5 = %zd char* = %zd\n\n",
        sizeof(v1), sizeof(v2), sizeof(v3),
        sizeof(v4), sizeof(v5),
        sizeof(char*));
    printf(
        "\
   v1[1] -> %s\n\
   v2[1] -> %s\n\
   v3[1] -> %s\n\
  *v4[1] -> %s\n\
   v5[1] -> %s\n ",
       v1[1], v2[1], v3[1], *v4[1], v5[1]);
    return 0;
}

 

também não compilou no v studio .

 

1656415620_errosdinovo.thumb.jpg.53052eff40d4b7ffe1f166858add641f.jpg

com tempo vou tentar descobrir o que pode ter acontecido .

Postado

image.png.23d27448c7473b56b33000223518b3ce.png

 

Sobre a linha 18: note as linhas 53/54 de seu programa
 

    const char antes[] = "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz";

 

e vai ver que são iguais.... É a maneira óbvia de testar TODAS as conversões ao mesmo tempo. Só não é a primeira porque preferi deixar a opção do autor @HUGO_dev_ze passando todas as letras a serem convertidas.

 

Em C as strings SEM a vírgula serão simplesmente concatenadas. É o normal e por isso não tem vírgula: é para deixar claro que se está concatenando as conversões da primeira fase com a conversão para maiúsculas que o autor fazia num loop adicional sem necessidade.

 

Sobre os erros C2440 sugiro rever as opções que compilação que usa.

 

C:\src\C\dvr>cl /W4 or.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30137 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

or.c
Microsoft (R) Incremental Linker Version 14.29.30137.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:or.exe
or.obj

C:\src\C\dvr>dir a.exe
 O volume na unidade C não tem nome.
 O Número de Série do Volume é 7E52-1BF2

 Pasta de C:\src\C\dvr

21/11/2021  13:42            66,207 a.exe
               1 arquivo(s)         66,207 bytes
               0 pasta(s)   41,105,997,824 bytes disponíveis

C:\src\C\dvr>

 

Em 32 bits com a última versão do compilador do Visual Studio gera o código normalmente

 

Se trocar para o gcc 11.2, última versão, e trocar no código os %zd nos printf() por %llu que é o que o gcc espera, compila igual

 


C:\src\C\dvr>gcc -Wall  -pedantic -std=c17 or-nozd.c

C:\src\C\dvr>

 

Resumo: teste com essas opções e me diga o que acontece

 

image.png.3e481b54fd126174f1eb24130b77e89c.png

 

@devair1010 Acho que não entendeu o que é N, apenas do comentário :) 

 

    // N testes, assim pode editar o vetor e criar outros
    size_t N = sizeof(entrada) / sizeof(char*);

 

Vai cancelar porque o vetor tem 5 opções e não 375!  "Só" por isso. Como te expliquei no texto essa conta serve para você poder ir estando sem ter que alterar o contador no programa....

 

Por isso te mostrei os programas adicionais com o layout da memória e os v1..v5: para você entender como isso fica na memória.

 

9 horas atrás, devair1010 disse:

o limite de size_t é 256 ? 

 

Não, size_t é long long int, 64 bits.

 

image.png.8f9f09fdd928332fea8aa7d00445bdbc.png

 

9 horas atrás, devair1010 disse:

testando o que está na matriz entrada , pois com números não precisa desses colchetes [0] "..."

e no codeblocks  , que creio que esteja usando o compilador GNU GCC e também o minGW , 

 

Sim, mas porque a mensagem diz entrada zero e você mostra entrada[1] ????????????????????

 

Imaginava que era esse compilador, mas qual a versão e quais opções está usando para compilar? já te perguntei isso antes e não respondeu.

 

9 horas atrás, devair1010 disse:

compilou de boa , e logo depois de mudar a locale saiu e retornou -1

 

Eu te expliquei uma boa razão para retornar -1: o locale oficial e tal. Não alterou ainda....

 

9 horas atrás, devair1010 disse:

também não compilou no v studio .

 

9 horas atrás, devair1010 disse:

com tempo vou tentar descobrir o que pode ter acontecido .

 

Pois é. 

 

Eu postei a saída do programa. Meu ambiente normal para usar aqui no forum é, para eu não gastar tempo demais, não mudar de máquina nem de ambiente nem nada. Então sempre uso Visual Studio. Algumas vezes VS Code e o gcc ou o clang. Mas na mesma máquina. E às vezes no Linux via WSL. 

 

Rodando seu programa agora no VS 16.11.7 deu o mesmo resultado

 

locale original: C
locale alterado para "pt_BR"

5 testes

    teste 1 de 5:
    antes:  "Hugo Jósé" (9)
    depois: "HUGO JOSE" (9)


    teste 2 de 5:
    antes:  "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇçabcdefghijklmnopqrstuvwxyz" (72)
    depois: "AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCCABCDEFGHIJKLMNOPQRSTUVWXYZ" (72)


    teste 3 de 5:
    antes:  "Clube do Hardware" (17)
    depois: "Clube do Hardware" (17)


    teste 4 de 5:
    antes:  "Ação ou Inércia?" (16)
    depois: "ACAO OU INERCIA?" (16)


    teste 5 de 5:
    antes:  "abcdefghijklmnopqrstuvwxyz" (26)
    depois: "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (26)

 

Note a "intrigante" string 2

 

 

Sobre o exemplo

 

Esse não é um programa assim sólido. 

 

Como te disse o melhor é usar uma tabela, é muito mais rápido.

 

E mais ainda, a entrada é const char[] então é arriscado converter na própria string. O ideal seria escrever

 

    char* tratar_string(const char*);

 

E retornar uma nova string convertida. Como é só para testar a conversão e não muda o tamanho é aceitável, mas não é certo.

 

 

  • Obrigado 1
Postado

Para dar um sentido ao que eu escrevi nos posts anteriores:

 

Essa é provavelmente a versão mais eficiente para um filtro desses:

 

char* tratar_string(const char* palavra)
{
#include "mapa.txt"
    char* nova = (char*)malloc(1 + strlen(palavra));
    char* p = nova;
    char* letra = palavra;
    while (*letra != 0) *p++ = idx[(const unsigned char)*letra++];
    *p = 0;
    return nova; // retorna o texto alterado
};

 

um loop, nenhum teste. 

 

O que tem em mapa.txt?

 


  const unsigned char idx[256] =
{

  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  // 000-015
 16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  // 016-031
 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  // 032-047
 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  // 048-063
 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  // 064-079
 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  // 080-095
 96,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  // 096-111
 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90, 123, 124, 125, 126, 127,  // 112-127
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,  // 128-143
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,  // 144-159
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,  // 160-175
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,  // 176-191
 65,  65,  65,  65,  65,  65, 198,  67,  69,  69,  69,  69,  73,  73,  73,  73,  // 192-207
208, 209,  79,  79,  79,  79,  79, 215, 216, 217,  85,  85,  85, 221, 222, 223,  // 208-223
 65,  65,  65,  65,  65, 229, 230,  67,  69,  69,  69,  69,  73,  73,  73,  73,  // 224-239
240, 241,  79,  79,  79,  79,  79, 247, 248,  85,  85,  85,  85, 253, 254, 255   // 240-255

}; // ARFNeto '21

 

Só a tabela. Nenhum código.

 

E para que o include? Pode ser apenas

 


char* tratar_string(const char* palavra)
{
    const unsigned char idx[256] =
    {

      0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  // 000-015
     16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  // 016-031
     32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  // 032-047
     48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  // 048-063
     64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  // 064-079
     80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  // 080-095
     96,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  // 096-111
     80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90, 123, 124, 125, 126, 127,  // 112-127
    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,  // 128-143
    144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,  // 144-159
    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,  // 160-175
    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,  // 176-191
     65,  65,  65,  65,  65,  65, 198,  67,  69,  69,  69,  69,  73,  73,  73,  73,  // 192-207
    208, 209,  79,  79,  79,  79,  79, 215, 216, 217,  85,  85,  85, 221, 222, 223,  // 208-223
     65,  65,  65,  65,  65, 229, 230,  67,  69,  69,  69,  69,  73,  73,  73,  73,  // 224-239
    240, 241,  79,  79,  79,  79,  79, 247, 248,  85,  85,  85,  85, 253, 254, 255   // 240-255

    }; // ARFNeto '21

    char* nova = (char*)malloc(1 + strlen(palavra));
    char* p = nova;
    char* letra = palavra;
    while (*letra != 0) *p++ = idx[(const unsigned char)*letra++];
    *p = 0;
    return nova; // retorna o texto alterado
};

 

Claro.

 

Só que isso serve para qualquer tabela. E é muito chato ficar digitando esses valores e conferindo.

 

Um pouco de metaprogramming em C

 

O programa gen.exe abaixo gera um arquivo no disco se receber o parâmetro, ou mostra na tela o resultado e se pode capturar em arquivo

 

PS M:\version2> ./gen tabela.txt

Gerado trecho de codigo em 'tabela.txt'
PS M:\Source\repos\chc20-1110-gentbl\version2> ./gen

  const unsigned char idx[256] =
{

  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  // 000-015
 16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  // 016-031
 32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  // 032-047
 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  // 048-063
 64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  // 064-079
 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  // 080-095
 96,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  // 096-111
 80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90, 123, 124, 125, 126, 127,  // 112-127
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,  // 128-143
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,  // 144-159
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,  // 160-175
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,  // 176-191
 65,  65,  65,  65,  65,  65, 198,  67,  69,  69,  69,  69,  73,  73,  73,  73,  // 192-207
208, 209,  79,  79,  79,  79,  79, 215, 216, 217,  85,  85,  85, 221, 222, 223,  // 208-223
 65,  65,  65,  65,  65, 229, 230,  67,  69,  69,  69,  69,  73,  73,  73,  73,  // 224-239
240, 241,  79,  79,  79,  79,  79, 247, 248,  85,  85,  85,  85, 253, 254, 255   // 240-255

}; // ARFNeto '21

// ou 

PS M:\version2> ./gen > mapa.txt

 

O programa que gera a tabela

 

Já postei antes algo assim aqui várias vezes

 

#include "stdio.h"
#include "string.h"
int main(int argc, char** argv)
{
	FILE* saida = stdout;
	int disco = 0; // gera arquivo?
	unsigned char ref[256] = { 0 };
	int out = 1;
	if (argc > 1)
	{
		saida = fopen(argv[1], "w");
		disco = 1;
	};


	// filtro
	for(int i = 0; i <= 255; i += 1) ref[i] = (unsigned char)i; // tudo igual
	const unsigned char antes[] =
		"ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
		"abcdefghijklmnopqrstuvwxyz";
	const unsigned char depois[] = 
		"AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCC"
		"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	int N = strlen((const char*)antes);
	for (int i = 0; i < N; i += 1) ref[antes[i]] = depois[i];
	// fim do filtro


	fprintf(saida, "\n  const unsigned char idx[256] =\n{\n\n");
	for (int i = 0; i < 240; i = i + 1)
	{
		fprintf(saida, "%3d, ", ref[i]);
		if (out % 16 == 0)
			fprintf(saida, " // %03d-%03d\n", out - 16, out - 1);
		out += 1;
	};
	// ultima linha
	for (int i = 240; i < 255; i = i + 1)
	{
		fprintf(saida, "%3d, ", ref[i]);
		out += 1;
	};
	// ultimo valor na ultima linha :) 
	fprintf(saida, "%3d  ", ref[255]);
	if (out % 16 == 0) fprintf(saida, " // %03d-%03d\n", out - 16, out - 1);
	out += 1;
	// fecha a declaracao
	fprintf(saida, "\n}; // ARFNeto '21\n");
	if (disco) fprintf(stderr, "\nGerado trecho de codigo em '%s'\n", argv[1]);
	return 0;
};	// main()

 

E é claro que é mais fácil trocar entre //filtro e //fim do filtro a lógica de cada situação e deixar o include no programa porque assim não precisa sequer editar o programa original

 

Um teste completo

 

//#include <ctype.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* tratar_string(const char*);

int main(void)
{
    const char* entrada[] =
    {
        "Húgô Jósé",
        "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇç"
        "abcdefghijklmnopqrstuvwxyz",
        "Clube do Hardware",
        "Ação ou Inércia?",
        "abcdefghijklmnopqrstuvwxyz"
    };

    // muda o locale para mostrar os simbolos "certos"
    printf("locale original: %s\n", setlocale(LC_ALL, NULL));
    char* local = setlocale(LC_ALL, "pt_BR");
    if (local == NULL) return -1;
    printf("locale alterado para \"%s\"\n", local);

    // N testes, assim pode editar o vetor e criar outros
    size_t N = sizeof(entrada) / sizeof(char*);
    printf("\n%zd testes", N);

    // faz os testes, claro
    char* result = NULL;
    for (size_t t = 0; t < N; t += 1)
    {
        printf("\n\
        teste %zd de %zd:\n\
        antes:  \"%s\" (%zd)\n",
            1 + t,
            N, entrada[t], strlen(entrada[t])
       );
        result = tratar_string(entrada[t]); // converte essa
        printf("        depois: \"%s\" (%zd)\n",
            result, strlen(result)
        );
        free(result);
    }
    return 0;
}

char* tratar_string(const char* palavra)
{
//#include "mapa.txt"
    const unsigned char idx[256] =
    {

      0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  // 000-015
     16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  // 016-031
     32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  // 032-047
     48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  // 048-063
     64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  // 064-079
     80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  // 080-095
     96,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  // 096-111
     80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90, 123, 124, 125, 126, 127,  // 112-127
    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,  // 128-143
    144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,  // 144-159
    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,  // 160-175
    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,  // 176-191
     65,  65,  65,  65,  65,  65, 198,  67,  69,  69,  69,  69,  73,  73,  73,  73,  // 192-207
    208, 209,  79,  79,  79,  79,  79, 215, 216, 217,  85,  85,  85, 221, 222, 223,  // 208-223
     65,  65,  65,  65,  65, 229, 230,  67,  69,  69,  69,  69,  73,  73,  73,  73,  // 224-239
    240, 241,  79,  79,  79,  79,  79, 247, 248,  85,  85,  85,  85, 253, 254, 255   // 240-255

    }; // ARFNeto '21

    char* nova = (char*)malloc(1 + strlen(palavra));
    char* p = nova;
    char* letra = (char*) palavra;
    while (*letra != 0) *p++ = idx[(const unsigned char)*letra++];
    *p = 0;
    return nova; // retorna o texto alterado
};

 

 

A saída do programa

 

locale original: C
locale alterado para "pt_BR"

5 testes
        teste 1 de 5:
        antes:  "Húgô Jósé" (9)
        depois: "HUGO JOSE" (9)

        teste 2 de 5:
        antes:  "ÄÅÁÂÀÃäáâàãÉÊËÈéêëèÍÎÏÌíîïìÖÓÔÒÕöóôòõÜÚÛüúûùÇçabcdefghijklmnopqrstuvwxyz" (72)
        depois: "AAAAAAAAAAAEEEEEEEEIIIIIIIIOOOOOOOOOOUUUUUUUCCABCDEFGHIJKLMNOPQRSTUVWXYZ" (72)

        teste 3 de 5:
        antes:  "Clube do Hardware" (17)
        depois: "Clube do Hardware" (17)

        teste 4 de 5:
        antes:  "Ação ou Inércia?" (16)
        depois: "ACAO OU INERCIA?" (16)

        teste 5 de 5:
        antes:  "abcdefghijklmnopqrstuvwxyz" (26)
        depois: "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (26)

 

  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!