Ir ao conteúdo
  • Cadastre-se
Drigs

C Iniciar cada palavra com letra maiscula sem função

Recommended Posts

Na tabela ASCII letra maiúsculas e minusculas são distanciadas por 32 posições então criei um if para diminuir 32 toda vez que tivesse um espaço e outro if para para a primeira posição diminuir 32, mas o if da primeira posição não funcionava então coloquei -16 e deu certo alguém poderia me explicar o porque e se tem algo desnecessário ou talvez uma forma melhor de se resolver, mas lembrem-se sem funções!!! 

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

int main(){   
 
    int i;    
    char frase[50]; 
       
    printf("Escreva a frase: ");    
    scanf("%[^\n]", frase);    
    
    for(i = 0; i < 50; i++){
        if(frase[0]){
            frase[0]= frase[0] - 16; //aqui esta o erro//
        }     
        if(frase== ' '){
        frase[i+1] = frase[i+1] - 32;
        }
    }
        
    printf("\nFrase convertida = %s\n", frase);
    
    return 0;
} 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Seu código está subtraindo 50 vezes o número 16 de frase[0], pois o código entra nesse if toda vez que o ciclo for é executado.

 

Então:

50 * 16 = 800

 

Mas o tipo char tem apenas 8 bits, indo de -128 até 127 com sinal, ou de 0 a 255 sem sinal, para um total de 256 números possíveis em ambos os casos. Então o que acontece é que você vai subtraindo até estourar o limite mínimo do tipo char (com ou sem sinal), e devido ao modo como números inteiros são armazenados em forma binária o que acontece é que quando a subtração estoura o mínimo na verdade o número vai para o valor máximo, como se os números fossem cíclicos.

 

Então fazendo a divisão inteira:

 

800 / 256 = 3, ou seja seu código faz 3 ciclos completos retornando ao número original.

800 % 256 = 32, ou seja restam 32, que é o valor total subtraído do char original no fim das contas.

  • Curtir 1
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, Drigs disse:

printf("Escreva a frase: ");

Encontrei outro erro: O que lhe garante que a frase já não começa com letra maiúscula, ou pior com número, ou sinal. Pois a pergunta do programa é "Escreva a frase".
 

Ex.:

Escreva a frase: Ás vezes ༼ಢ_ಢ༽
▍

 

 

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

1#
Seu if está errado:

1 hora atrás, Drigs disse:

if(frase[0]){
  
}

 

Você apenas colocou um caractere como condição. Por exemplo, se eu escrever "joao de santo cristro", a posição 0 terá o "j", correto? logo, seria o mesmo que fazer:

if("j") {
  
}

Daí, a condição está sempre dando verdadeira (obs.: não sei porque!). Seria como o if não existisse, pois como é um valor estático, o resultado da expressão sempre será igual!!! (sempre será verdadeiro).

 

Daí, "funcionou" com o -16 devido ao explicado por @isrnick.

 

 

 

2#

O que você está verificando é se é a primeira posição, logo seria algo como:

if(i==0)

 

 

 

3#

Esses 2 if são mutuamente excludentes, logo precisa utilizar um else. Não sei se vai ficar mais eficiente, me refiro a lógica.

 

Outra coisa, a depender faz a atualização da primeira posição antes do for, e dentro só deixa o segundo if.

 

 

 

4#

Acho que não precisa fazer sempre até 50, mais correto seria fazer de 0 até o tamanho da frase digitada.

 

 

 

5#

Não precisa de {}, pois só tem uma instrução nos if, assim como no else.

 

 

 

6#

Poste o enunciado completo, pois as características do código depende do que foi solicitado. (não adianta fazer um código "certo" para o "problema errado". Seria como um médico fazer uma cirurgia perfeita na perna do paciente, mas ele foi internado para cirurgia de miopia...).

 

 

Por exemplo, e se eu já digitar as palavras com as iniciais em maiúsculo... esse código vai funcionar? creio que não... mas e aí, era para acontecer o que?

 

***

 

Por ai vai.

 

 

  • Curtir 2
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu sei, mas o exercício não pede isso, ele é introduzido somente com minusculas e o objetivo é colocar a primeira de toda palavra com maiúscula.

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 minuto atrás, Drigs disse:

eu sei, mas o exercício não pede isso, ele é introduzido somente com minusculas e o objetivo é colocar a primeira de toda palavra com maiúscula.

 

Vide:

16 minutos atrás, Simon Viegas disse:

Poste o enunciado completo, pois as características do código depende do que foi solicitado.

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
8 minutos atrás, Simon Viegas disse:

Creio eu que seja um problema secundário... ou seja, a falha já ocorre mesmo digitando uma frase ideal... como "bora baea minha porreta".

Algo a ir pensando desde de agora, inclusive investigando se é ou não maiúscula da inicio a solução do problema, pois a distancia entre Z - A é igual a distância entre a - z. Com isso basta obter a diferença e somar:

 

Seja x:= frase[0]

Se A <= x <= Z: x é maiúscula nada se fazer

Se a <= x <= z: então faça: x = x-a + A.

Resolvido :thumbsup:

Claro que pode também deslocar toda a distância -16 como propostos. Fica essa solução como alternativa

adicionado 2 minutos depois

Depende mesmo do enunciado.

adicionado 4 minutos depois
9 minutos atrás, Drigs disse:

eu sei, mas o exercício não pede isso, ele é introduzido somente com minusculas e o objetivo é colocar a primeira de toda palavra com maiúscula.

Isso só facilitou, basta agora saber quais os recursos que podem e devem ser usados, segundo o enunciado. 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sobre:

2 minutos atrás, AnsiC disse:

Algo a ir pensando desde de agora, inclusive investigando se é ou não maiúscula da inicio a solução do problema, pois a distancia entre Z - A é igual a distância entre a - z. Com isso basta obter a diferença e somar:

 

Seja x:= frase[0]

Se A <= x <= Z: x é maiúscula nada se fazer

Se a <= x <= z: então faça: x = x-a + A.

Resolvido :thumbsup:

 

Foi mal... eu tinha respondido errado. Não tinha visto o "OUTRO erro", rs. Tanto que apaguei logo depois!!! (acho que não deu tempo).

 

 

 

Sobre:

8 minutos atrás, AnsiC disse:

Claro que pode também deslocar toda a distância -16 como propostos. Fica essa solução como alternativa

Esse -16 foi explicado por @isrnick, ou seja, resumidamente o if está errado, e fez várias subtrações... utilizando -16, coincidiu com a resposta certa.

 

 

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
14 minutos atrás, AnsiC disse:

Algo a ir pensando desde de agora, inclusive investigando se é ou não maiúscula da inicio a solução do problema, pois a distancia entre Z - A é igual a distância entre a - z. Com isso basta obter a diferença e somar:

 

Seja x:= frase[0]

Se A <= x <= Z: x é maiúscula nada se fazer

Se a <= x <= z: então faça: x = x-a + A.

Resolvido :thumbsup:

Claro que pode também deslocar toda a distância -16 como propostos. Fica essa solução como alternativa

adicionado 2 minutos depois

Depende mesmo do enunciado.

adicionado 4 minutos depois

Isso só facilitou, basta agora saber quais os recursos que podem e devem ser usados, segundo o enunciado. 

posso usar as letras invés dos números da tabela ASCII, pra indicar entre elas?

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
16 minutos atrás, Drigs disse:

posso usar as letras invés dos números da tabela ASCII, pra indicar entre elas?

 

Sim.

 

Veja como fica o código checando se é uma letra minúscula antes de transformar em maiúscula, e usando apenas caracteres ao invés de constantes (como 32 que usou no seu código):

 

#include <stdio.h>

int main(){   
 
    int i;    
    char frase[50]; 
       
    printf("Escreva a frase: ");    
    scanf("%[^\n]", frase);    
    
    for(i = 0; i < 50 && frase[i] != '\0'; i++){
        if( (i == 0 || frase[i-1] == ' ') && frase[i] >= 'a' && frase[i] <= 'z' ){
            frase[i] = frase[i] - 'a' + 'A';
        }
    }
        
    printf("\nFrase convertida = %s\n", frase);
    
    return 0;
}

 

Isso funciona pois o tipo char é um tipo de números inteiros (com 8 bits na forma binária).

 

O que acontece quando imprimimos usando %c ou %s é uma conversão usando a tabela de caracteres, para imprimir o caractere correspondente ao número na variável char.

 

  • Curtir 1
  • Obrigado 2
  • Confuso 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
29 minutos atrás, Drigs disse:

posso usar as letras invés dos números da tabela ASCII, pra indicar entre elas?

Isso mesmo, como já exemplificado, as chamadas literais~char são representações dos valores da tabela ASCII dentro do nosso código-fonte. Inclusive recomendam o uso das literais sempre.

 

PS.:

Fica mais bonito de se ver também ;)

  • Curtir 4

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sobre:

48 minutos atrás, isrnick disse:

if( (i == 0 || frase[i-1] == ' ') && frase[i] >= 'a' && frase[i] <= 'z' ){

 

Ali no [i-1], com i=0, não estaria acessando uma posição inexistente do vetor? isso não poderia dar algum problema?

 

adicionado 2 minutos depois

Seria algo como:

if( (0 == 0 || frase[-1] == ' ') && frase[0] >= 'a' && frase[0] <= 'z' ) {

Ou existe algum tratamento para posições negativas?

adicionado 6 minutos depois

Outra dúvida:

As letras com acentos, e outras como 'ç', ficam entre 'a' e 'z' ou para tratar esses casos precisaria utilizar outras faixas?

Compartilhar este post


Link para o post
Compartilhar em outros sites
5 minutos atrás, Simon Viegas disse:

Sobre:

 

Ali no [i-1], com i=0, não estaria acessando uma posição inexistente do vetor? isso não poderia dar algum problema?

 

 

Não. Pois a avaliação booleana "Verdadeiro OU qualquer-coisa" sempre resulta em "Verdadeiro".

 

Então em:

i == 0 || frase[i-1] == ' '

 

Se a primeira parte for verdadeira a segunda parte não precisa ser checada, logo nesse caso por otimização essa segunda parte nem se quer é executada, pois é desnecessário. A segunda parte só é executada e verificada se a primeira parte for falsa. Portanto nunca acessa a posição que não existe.

 

 

 

Mas se tivesse invertido a ordem das duas partes ficando:

frase[i-1] == ' ' || i == 0

Realmente ocorreria um acesso a uma posição do vetor que não existe.

 

Logo, você precisa já saber que este é o modo/sequência em que o código é executado, e como se comporta, e organizá-lo tal que não ocorra o acesso errado.

 

 

 

Isso não é algo exclusivo da linguagem C, todas as linguagens de programação que já usei fazem este tipo de otimização em operações booleanas (só executa e avalia a segunda parte se ela for afetar o resultado).

 

Veja o caso do E:

 

"Falso E qualquer-coisa" sempre resulta em Falso. Logo, se a primeira parte é falsa não checa a segunda parte.

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante

@Drigs Olá. Para facilitar a resolução desse exercício recomendaria dividir o mesmo em duas partes.

1. Trate da 1ª palavra da frase

2. Trate do restante da frase

Foi essa a forma q usei p resolver o exercício

 
adicionado 23 minutos depois

Só q o @isrnick não pensou assim. Resolveu tudo em um for só.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
5 horas atrás, Simon Viegas disse:

As letras com acentos, e outras como 'ç', ficam entre 'a' e 'z' ou para tratar esses casos precisaria utilizar outras faixas?

É outra faixa sim que integra certa dificuldade de implementação. A complexidade engloba até codificação de arquivos. Não é difícil de fazer, é difícil de ensinar. 

 

 

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante

@AnsiC É correto usar o termo "Capitalizar" a primeira letra de cada palavra para um exercício como esse?

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
8 minutos atrás, giu_d disse:

@AnsiC É correto usar o termo "Capitalizar" a primeira letra de cada palavra para um exercício como esse?

 

Acho que sim.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro 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 publicações 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

×