Ir ao conteúdo
  • Cadastre-se

C comparar string no switch case


UmPrograma

Posts recomendados

Boa tarde, pessoal.

vocês poderiam me ajudar/explicar se é possivel fazer uso de switch case com string. 

E se possivel , me ajudar a resolver o seguinte exercicio.

Ficarei grato.

/**17. Ler uma variavel string (3 caracteres) que pode assumir um valor entre seg, ter, qua, ´
qui, sex, sab, dom, e imprimir as seguintes mensagens, respectivamente: segunda-feira,
terc¸a-feira, quarta-feira, quinta-feira, sexta-feira, sábado e domingo. Utilize o comando ´
”case”.**/
#include <stdio.h>
#include <string.h>
main (){
    char str[3];

    printf("Informe a string: ");
    gets(str);

    switch (str){
case "seg" :
    printf("E segunda-feira.");
    break;
case "ter":
    printf("Terca-feira");
    break;
case "qua":
    printf("Quinta feira");
    break;
case "sex":
    printf("Sexta feira");
    break;
case "sab":
    printf("sábado");
    break;
case "dom":
    printf("domingo");
    break;
default:
    printf("Nao e dia da semana.");
    break;

    }


return 0;
}

 

  • Amei 1
Link para o comentário
Compartilhar em outros sites

Primeiramente, para armazenar uma string com n caracteres não nulos um vetor de caracteres deve ter no mínimo comprimento n+1, para armazenar todos os caracteres não nulos da string, mais o caractere nulo '\0' que indica o fim da string.

 

Ex: Para a string "ovo" ser guardada em um vetor de caracteres, deverão ser armazenados os caracteres 'o', 'v', '0' e '\0', então o comprimento do vetor deve ser de no mínimo 4 posições ( char vetorDeCaracteres[4] = "ovo"; ).

 

Mas seu vetor tem apenas 3 posições para armazenar strings de 3 caracteres não nulos ("seg", "ter", "qua", etc), o que está errado.

 

 

 

Switch-case faz comparações de igualdade, como o operador ==, comparando os bits de um valor, logo do mesmo modo que não podemos comparar strings usando ==, também não podemos fazê-lo com switch-case.

 

 

 

Eu consigo pensar em 2 possibilidades para resolver esse problema usando switch-case:

 

1 - Podemos fazer operações matemáticas (somar ou multiplicar, entre si e/ou com constantes extras) com os 3 caracteres de cada palavra.

 

Veja uma exemplo usando soma dos 3 caracteres:

switch (str[0] + str[1] + str[2]){
    case 's'+'e'+'g':
        
        break;
    case 't'+'e'+'r':
        
        break;
}

Contanto que as operações matemáticas resultem em números diferentes em todos os casos, o switch-case vai funcionar corretamente.

 

 

2 - Note que nas 7 strings tem 1 posição em que a letra é diferente em todas elas, a terceira letra da string, logo podemos verificar apenas essa letra:

 

switch(str[2]){
    case 'g': //seg
        
        break;
    case 'r': //ter
        
        break;
}

Mas isso é uma gambiarra, pois se alguém digitar "XYg" vai cair na segunda-feria...

  • Curtir 1
  • Obrigado 2
  • Amei 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Vou tentar complementar...

 

Pelo que eu vi, apenas ocorre uma limitação/característica da linguagem, ou seja, o C e C++ não aceitam "string" (vetor de char) no swtch. Aí, teria que fazer, por exemplo esses malabarismo do @isrnick.

 

Ou como sugerido por @Math.Pi, usa if/else em vez de swtch.

 

 

obs.: Pelo que eu vi, por exemplo, no C# funcionaria usar "string".

 

RESUMINDO:

32 minutos atrás, Josesousa disse:

então nao tem como eu resolver o exercicio.

Pensei que dava para resolver. :(

 

Não é que não tinha como resolver o exercício, apenas que a forma que você tentou resolver não é válida (usar string em switch)... Teria que fazer os ajustes ou tentar outra coisa.

  • Curtir 3
Link para o comentário
Compartilhar em outros sites

Fiz a verificação das somas dos caracteres das 7 strings:

's' + 'e' + 'g'  =  115 + 101 + 103  =  319
't' + 'e' + 'r'  =  116 + 101 + 114  =  331
'q' + 'u' + 'a'  =  113 + 117 +  97  =  327
'q' + 'u' + 'i'  =  113 + 117 + 105  =  335
's' + 'e' + 'x'  =  115 + 101 + 120  =  336
's' + 'a' + 'b'  =  115 +  97 +  98  =  310
'd' + 'o' + 'm'  =  100 + 111 + 109  =  320

E todas as somas dão valores diferentes, logo vai funcionar usando a soma.

 

 

 

Mas como é possível ver algumas das somas resultaram em valores bem próximos uns dos outros, mesmo que as strings sejam bem diferentes, como "seg" (319) e "dom" (320), ou então "qui" (335) e "sex" (336).

 

Daí fica evidente que haverão outras strings de 3 caracteres cuja soma dos caracteres resultam em valores iguais a estes. De fato é fácil encontrá-los basta somar e subtrair o mesmo número de 2 caracteres diferentes da string:

('s' - 2) + ('e' + 2) + 'g'  =  'q' + 'g'+ 'g'  =  319

E podemos continuar somando e subtraindo um número para achar outras:

('q' - 1) + 'g'+ ('g' + 1)  =  'p' + 'g' + 'h'  =  319

Logo, se a string analisada for "qgg" ou "pgh" o programa vai entrar no case do "seg".

 

Isso não é um problema se houver garantia de que somente as strings válidas vão ser entradas no switch-case, mas esse não é o caso quando essa string está sendo digitada pelo usuário, onde a string pode ser qualquer coisa.

 

 

 

Então seria interessante achar um modo de combinar os caracteres com operações de modo que jamais resulte em strings repetidas.

 

Para achar uma solução considerei o fato de que o tipo char é um tipo inteiro com 8 bits, ou seja são números variam de -128 até 127 com sinal, ou de 0 até 255 sem sinal.

 

Ou seja, os números tem no máximo 3 dígitos (na base 10), então poderia fazer:

str[0] * 1000 * 1000 + str[1] * 1000 + str[2]

Assim iria adicionando zeros ao fim dos números, e por terem só 3 dígitos eles seriam separados totalmente na soma, por exemplo no caso de "seg" ficaria:

115 * 1000000 + 101 * 1000 + 103  =  115000000 + 101000 + 103  =  115101103

Assim, certamente nunca haveriam 2 somas iguais para quaisquer 3 caracteres.

 

 

Mas ir multiplicando por potências de 1000 é demais para números que vão no máximo até 255, podemos achar números menores que 1000 que podem servir para sempre resultar em somas únicas, sem repetição, então a questão é qual seria o menor número possível que poderíamos usar para garantir isto?

 

O número é 256 (= 28), que seria o primeiro número com 9 bits em forma binária, 1 a mais que o número de bits do tipo char, ficando igual a 1 0000 0000 em binário. Pois da mesma forma que no caso de 1000 na base 10, um número binário quando multiplicado por 1 0000 0000 binário vai adicionar 8 zeros ao final do número, ou seja desloca-lo para a esquerda em 8 bits. Assim, quando somar o resultado a outro número char os bits relevantes nunca se sobrepõem, novamente ficando totalmente separados na soma.

 

Então nosso switch-case fica assim:

switch (str[0]*65536 + str[1]*256 + str[2]){
    case 's'*65536+'e'*256+'g':
        
        break;
    case 't'*65536+'e'*256+'r':
        
        break;
}

Onde 256 * 256 = 65536.

 

 

 

Mas já que mostramos que multiplicar por 256 desloca o número binário em 8 bits para a esquerda, então também poderíamos usar o operador binário de deslocamento << , ao invés de multiplicação, para deslocar para esquerda em 8 bits por vez.

 

Ficando assim:

switch ((str[0] << 16) + (str[1] << 8) + str[2]){
    case ('s' << 16) + ('e' << 8) + 'g':
        
        break;
    case ('t' << 16) + ('e' << 8) + 'r':
        
        break;
}

 

Agora temos algumas opções de soluções completas, para que o switch-case certifique-se de que a string analisada seja exatamente uma das strings válidas.

  • Curtir 1
  • Obrigado 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

@isrnick GENIAL...

 

Mas, confesso que nao entendi por completo o que voce escreveu ai nao. (risos)

Eu ainda nao entendo isso de deslocamento. <<  (realmente nao sei)

 

E uma pergunta, como faço para saber o numero correspondente de uma letra?

 

Fico feliz em saber que arrumou uma forma de resolver o problema... Agradecido.....

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

1 hora atrás, Josesousa disse:

Mas, confesso que nao entendi por completo o que voce escreveu ai nao. (risos)

Eu ainda nao entendo isso de deslocamento. <<  (realmente nao sei)

:lol:

 

São operadores de deslocamento de bits de um número binário, para a esquerda << ou para a direita >>.

https://pt.wikipedia.org/wiki/Operadores_em_C_e_C%2B%2B#Operadores_de_deslocamento_de_bits

 

Se quiser pesquise sobre o funcionamento dos operadores binários em C. Mas eu não me preocuparia com eles até precisar deles, pois você vai ter que lidar muito com números binários e afins para entendê-los.

 

 

1 hora atrás, Josesousa disse:

E uma pergunta, como faço para saber o numero correspondente de uma letra?

 

Consulte tabelas de caracteres, a mais simples e mencionada, e que já lista os caracteres básicos (letras, números, espaço, nova linha, operadores matemáticos, etc) é a tabela ASCII.

 

https://www.asciitable.com/

 

As demais tabelas, mais completas, costumam seguir a mesma numeração para estes caracteres básicos.

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

 

Em 09/06/2018 às 00:16, Josesousa disse:

Eu ainda nao entendo isso de deslocamento. <<  (realmente nao sei)

Realmente é uma pena, pois é muito legal! E não é difícil de entender; no caso foram 3 char [1 byte cada] enviados para 1 int [4 bytes cada].  Bacana !

 

Que vai gerar números pouco a nada de sequenciais, vi comentário de que essa é a forma mais ingênua de se usar Switch. Switch é muito melado, clausula IF é muito melhor.

 

Se não quiser usar deslocamento de bits, colocar  o código  valor das três letras direto no Label case é outro caminho que leva mesmo lugar. Use o programinha abaixo para visualizar o inteiro que resulta da combinação:

#include <stdio.h>

int main()
{
    char str[4]; // Tem a mesma quantidade de bytes de int 
    
    scanf("%s", str);
    printf("CODIGO -> NUMERO\n");
    printf("%s -> %d: ", str, *(int*)str);
    
    switch(*(int*)str)
    {
        case 7171940: 
            printf("Domingo\n");
    }
    return 0;
}

 

~~ / ~~

Boa Sorte

  • Confuso 1
Link para o comentário
Compartilhar em outros sites

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...