Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
Josesousa

C comparar string no switch case

Recommended Posts

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;
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde.

Switch só funciona com char (caractere simples) e int.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Math.Pi então nao tem como eu resolver o exercicio.

Pensei que dava para resolver. :(

Compartilhar este post


Link para o post
Compartilhar em outros sites
Postado (editado)

Até dá se você usar strcmp. Vai ter mais um trabalho pra trocar a string por um número e depois passar para o case. Esse trabalho seria resumido se não usasse o case ou se a entrada de dados fosse um número.

Editado por Math.Pi

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ah sim!

Eu tentei usar no case > case strcmp("seg", str).

Mas ai no caso nao funciona .......:(

 

Transformar o nome em numero da muito trabalho (nunca tentei, mas ja me deparei com alguns codigos que faziam isso).

 

Com if else seria mais pratico......

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não é no case. Vai ter que criar uma estrutura condicional antes do case. E o número resultante será utilizado no case.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim amigo, entendi (apesar de nao saber fazer isso AINDA ahahaha)

Depois vou tentar implementar isso.

:thumbsup:

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Postado (editado)

Mais ou menos assim:

 

if (strcmp(nome,”joao”) == 0){
	numero = 1;
}
else if (strcmp(nome,”rodrigo”) == 0){
	numero = 2;
}
else if//.... etc
  
  
switch(numero){
  case 1: //etc
  case 2: //etc
}

 

Editado por Math.Pi
  • Obrigado 1

Compartilhar este post


Link para o post
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 1
  • Amei 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esse primeiro método é interessante. Não sabia que era possível.

Compartilhar este post


Link para o post
Compartilhar em outros sites

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 2

Compartilhar este post


Link para o post
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.

  • Obrigado 1
  • Amei 1

Compartilhar este post


Link para o post
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 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Postado (editado)
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.

Editado por isrnick
  • Curtir 1

Compartilhar este post


Link para o post
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

Editado por AnsiC
  • Confuso 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso esta me parecendo ponteiro. (Não cheguei a estudar ponteiro ainda).

Mas estou dando uma olhado por fora.....

  • Obrigado 1

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






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

×