Ir ao conteúdo

Posts recomendados

Postado

Estou tentando comparar dois chars fornecidos pelo usuário pelo if, exemplo: 

Eu sei que da pra fazer com strcmp, mas queria fazer sem biblioteca 

 

main(){

char a, b;

printf("Digite a: ");
scanf("%s", &a);
printf("Digite b: ");
scanf("%s", &b);
if(a == b)
    printf("Igual");
    else
        printf("Diferente");
}

 

  • Obrigado 1
Postado

@Victor Machida     teste esse aqui :

#include <stdio.h>
int main(){
    char a, b;
    printf("Digite a: ");
    scanf("%c",&a);
    printf("Digite b: ");
    fflush(stdin);
    scanf("%c",&b);
    if(a == b)
        printf("Igual\n\n");
    else
        printf("Diferente\n\n");
    return 0;
}

 

  • Curtir 2
Postado
30 minutos atrás, Victor Machida disse:

Eu sei que da pra fazer com strcmp, mas queria fazer sem biblioteca

 

Não, não dá.

 

strcmp() compara strings, sequências de char terminadas por um 0, o tal null ou '\0'.

 

Para comparar os char use mesmo um if. E repare na diferença entre constantes char e constantes string em C.

Um char é 'a' e um string com um char é "a". Estas são constantes.  E você declararia como constantes em seu programa por exemplo

const char letra_1 = 'a';
const char* string_1 = "a";

 

Essa distinção é um inferno para quem está aprendendo isso. As funções de string.h tratam strings e não char.

 

scanf() trata entrada formatada --- scan formatted input ---. E também é um inferno para quem está aprendendo. Não entendo porque os instrutores começam por ensinar isso para ler entrada do teclado.

 

scanf() retorna um número que você não leu. Sugiro usar esse valor de retorno, que é o número de itens lidos. Se quer ler um char use getchar(), mais simples e direto ao assunto.

 

scanf() é uma rotina enjoada. Muito útil para o que foi feita. Perfeita para ler entrada formatada. Mas usada a olho ela é ativa, "come" valores da entrada, deixa o usuário zoar toda a entrada, cancela seu programa toda hora e por aí vai.

 

Em especial se você não ler o valor de retorno, o que aparentemente ninguém que escreve aqui no forum faz.

 

Exemplo 1: o seu programa

#include "stdio.h"
main()
{
    char a;
    printf("Digite a: ");
    scanf("%s", &a);
}

cancela. Porque? 

a variável char tem um byte. Só um. Você pediu para ler uma string usando a máscara "%s". Máscara é um nome comum para essa instrução de formato, esse "%s". Podia escrever assim também

#include "stdio.h"
main()
{
    const char* mascara = "%s";
    char letra;
    printf("Digite uma letra: ");
    scanf(mascara, &letra);
}

É só um exemplo igual. E vai cancelar igualzinho. A razão: com "%s" scanf() vai tentar ler uma string: tudo até encontrar um espaço ou o fim da linha. Mesmo que você digite uma e uma só letra e ENTER scanf() vai tentar gravar o tal 0 que termina a string e como o endereço que passou corresponde a um único byte.... Adeus programa.

 

E se fossem duas letras?


#include "stdio.h"
main()
{
    const char* mascara = "%s";
    char letras[2];

    letras[0] = 50;
    letras[1] = 55;
    printf("Digite uma letra: ");

    scanf(mascara, letras);
    printf("valores em letras: '%d'e '%d'\n", letras[0], letras[1]);
    return;
}

Se o cara digitar a e ENTER vai sair

Digite uma letra: a
valores em letras: '97'e '0'

Pois é. Não cancelou. Mas leu DUAS coisas. Eram 50 e 55 antes de ler e 97 e 0 depois de ler. Pois é: 97 

é o valor do 'a' e 0 é o tal null que termina a string. 

 

Mas se o cara digita ab e ENTER vai cancelar também porque serão 3 posições  e não terá onde por. Acho que já entendeu.

 

E se fosse tentar ler duas letras, em dois scanf()?

#include "stdio.h"
main()
{
    const char* mascara = "%s";
    char letras[2];

    letras[0] = 50;
    letras[1] = 55;
    printf("Digite uma letra: ");

    int n = scanf(mascara, letras);
    printf("valores em letras: '%d'e '%d'\n", letras[0], letras[1]);
    printf("scanf() retornou %d\n", n);
    return;
}

Teria mostrado para a e enter

Digite uma letra: a
valores em letras: '97'e '0'
scanf() retornou 1

Porque scanf() leu um único elemento, através da máscara "%s"...

 

Mudando a máscara para "%c" que le uma letra só:

#include "stdio.h"
main()
{
    const char* mascara = "%c";
    char letra;
    printf("Digite uma letra: ");
    int n = scanf(mascara, &letra);
    printf("valores em letra: '%d'\n", letra);
    printf("scanf() retornou %d\n", n);
    return;
}

mostra

Digite uma letra: a
valores em letra: '97'
scanf() retornou 1

Muito bom. Mas... E se fossem duas letras?

#define _CRT_SECURE_NO_WARNINGS

#include "stdio.h"
main()
{
    const char* mascara = "%c";
    char letra;

    printf("Digite uma letra: ");
    int n = scanf(mascara, &letra);
    printf("valores em letra: '%d'\n", letra);
    printf("scanf() retornou %d\n", n);

    printf("Digite outra letra: ");
    n = scanf(mascara, &letra);
    printf("valores em letra: '%d'\n", letra);
    printf("scanf() retornou %d\n", n);
    return;
}

Sai isso

Digite uma letra: a
valores em letra: '97'
scanf() retornou 1
Digite outra letra: valores em letra: '10'
scanf() retornou 1

E não vai nem tentar ler a segunda letra: o 10 é o código do ENTER digitado depois do 'a' e scanf() usou para alimentar a segunda chamada. 

 

Há muitas maneiras de adequar a máscara de scanf() para ler múltiplos valores. Sugiro ler a tabela de especificadores no manual e experimentar um pouco. Mas entenda que  o propósito de scanf() não é ler valores do teclado. E use o valor de retorno, em especial se tenta ler mais de um valor na mesma chamada.

 

E usando getchar() para ler as letras?

getchar é mais simples afinal e só lê uma letra...

#define _CRT_SECURE_NO_WARNINGS

#include "stdio.h"
main()
{
    const char* mascara = "%c";
    char letra;
    char linha[41];

    printf("Digite uma letra: ");
    letra = getchar();
    printf("valores em letra: '%d'\n", letra);

    printf("\n");
    printf("Digite outra letra: ");
    letra = getchar();
    printf("valores em letra: '%d'\n", letra);
    return;
}

E aí? 

Digite uma letra: a
valores em letra: '97'

Digite outra letra: valores em letra: '10'

Deu na mesma... Não deu tempo de digitar a segunda letra

 

Então e se eu usar fgets() para ler tudo que tem na linha até o final? Aí eu posso usar espaços, ler nome e sobrenome por exemplo....

Claro que estou recortando e colando no mesmo programa, ok? 

#include "stdio.h"
main()
{
    const char* mascara = "%c";
    char letra;
    char linha[41];

    printf("Digite uma letra: ");
    letra = getchar();
    printf("valores em letra: '%d'\n", letra);

    printf("\n");

    printf("Digite outra letra: ");
    letra = getchar();
    printf("valores em letra: '%d'\n", letra);

    printf("\nDigite qalquer coisa e tecle enter: ");
    fgets(linha, 40, stdin);
    printf("O que leu em linha: '%s'\n", linha);
    return;
}

Ainda vai claro passar pelo segundo getchar() direto, claro

Digite uma letra: a
valores em letra: '97'

Digite outra letra: valores em letra: '10'

Digite qalquer coisa e tecle enter: a b
O que leu em linha: 'a b
'

Mas aí eu digitei a espaço b e enter mas era para imprimir entre ' e ' e pulou uma linha #$%#$%#$!

Um inferno isso. Mas está no manual: fgets() coloca um zero no fim e em geral é bom porque pode usar o valor lido direto naquelas rotinas que tratam string, por exemplo, já que todas esperam um 0 no final.  Mas aqui deu m#$%a...

 

Então colocando um for para mostrar tudo o que veio e tirando o zero do fim: 

#include "stdio.h"
main()
{
    const char* mascara = "%c";
    char letra;
    char linha[41];

    printf("Digite uma letra: ");
    letra = getchar();
    printf("valores em letra: '%d'\n", letra);

    printf("\n");

    printf("Digite outra letra: ");
    letra = getchar();
    printf("valores em letra: '%d'\n", letra);

    printf("\nDigite qalquer coisa e tecle enter: ");
    fgets(linha, 40, stdin);
    printf("O que leu em linha: '%s'\n", linha);
    printf("leu %d caracteres\n", strlen(linha));
    for(int i=0; i<strlen(linha); i = i + 1)
        printf("%d ", linha[i]);
    linha[strlen(linha) - 1] = 0;
    printf("\nlinha agora: '%s'\n", linha);
    return;
}

E aí imprime como esperado

Digite uma letra: a
valores em letra: '97'

Digite outra letra: valores em letra: '10'

Digite qalquer coisa e tecle enter: a b
O que leu em linha: 'a b
'
leu 4 caracteres
97 32 98 10
linha agora: 'a b'

Por isso é que em geral ao usar getchar() ou scanf() para ler da entrada padrão tem essa mística de "limpar o buffer" que é simplesmente: depois de ler um valor ler o resto que tem até o enter e descartar. 

 

Tire suas conclusões e pergunte algo se precisar, claro....

 

@devair1010 fflush(stdin) é inócuo. fflush() só atua em streams de saída. Na entrada o comportamento mais comum é que não aconteça nada. A documentação diz: indefinido. A Microsoft parece fazer um flush em stdin mas não estou certo de que seja sempre e que não dê problema quando stdin está redirecionado.
 

 

 

 

  • Obrigado 3

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