Ir ao conteúdo
  • Cadastre-se

C++ Como capturar o valor das setas ?


Code guy
Ir à solução Resolvido por Simon Viegas,

Posts recomendados

Fiz um código para tenta capturar o valor das setas do teclado mas as setas geram 2 valores: 224 e o valor das setas(72, 75, 77, 80), como faço para capturar apenas o valor das setas? Código abaixo:

#include <stdio.h>
#include <conio.h>

int posicao;

int main()
{
    
    do{
    posicao = getch();
    printf("%d\t",posicao);
    }while(posicao!=13);
  
    return 0;
}

(Estou usando: windows, GNU GCC compiler)

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

  • Membro VIP

Olá @Code guy.
 

11 horas atrás, Code guy disse:

A função kbhit() só reconhece se a tecla foi pressionada e não retorna valor.

Mas pode deixar, ja resolvi o programa. 

 

Resolveu como? por favor, poste a sua solução para assim poder servi de base para outros usuários.

 

No aguardo.

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

Muito obrigado pela sua solução Vangodp.

A minha solução foi a seguinte:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include<locale.h>

int seta,posicao=0;
                                         ///CIMA = 72
                                         ///BAIXO = 80
void MenuposicaoS();

//

int main()
{
    setlocale(LC_ALL,"portugese");
    MenuposicaoS();  ///Função(logo abaixo)
 
    return 0;
}

//
void MenuposicaoS(){
    do{

    system("cls");

    if(seta==72)
        posicao++;
    if(seta==80)
        posicao--;

    if(posicao>3)
        posicao=0;
    if(posicao<0)
        posicao=3;

    if(posicao==0)
        printf("\t\tUORDI\n\t  Novo+ \n\n\n\t->");
    if(posicao==1)
        printf("\t\tUORDI\n\t  Novo+ \n\n\t->");
    if(posicao==2)
        printf("\t\tUORDI\n\t  Novo+ \n\t->");
    if(posicao==3)
        printf("\t\tUORDI\n\t->Novo+ ");

        seta = getch();
    }while(seta!=13);
}    ///estou criando um programa para armazenar texto por isso o nome:UORDI

obs.: A minha solução foi simplermente ignorar o 224 e só fazer uma função se o usuario digitar a seta para cima ou para baixo.

Dica: Coloquei 3 barras ao invés de 2 nos comentários porque o azul(no code::blocks) dá mais destaque.

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

Poderia usar GetAsyncKeyState e mostrar o valor da constante definido equivalente a cada tecla(VK_UPARROW, VK_DOWN, VK_LEFT, VK_RIGHT)

 

if (GetAsyncKeyState(VK_UP)&1)
    // Seta para cima pressionada
else if (GetAsyncKeyState(VK_DOWN)&1)
    // Seta para baixo pressionada
else if (GetAsyncKeyState(VK_LEFT)&1)
    // Seta para esquerda pressionada
else if (GetAsyncKeyState(VK_RIGHT)&1)
    // Seta para direita pressionada

 

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

  • Membro VIP
  • Solução

Olá @Code guy.

 

Como o código já está "pronto", vou tentar levantar algumas questões:

 

 

1) LEITURA DA TECLA PELO GETCH()

13 horas atrás, Code guy disse:

obs.: A minha solução foi simplermente ignorar o 224 e só fazer uma função se o usuario digitar a seta para cima ou para baixo.

 

No caso, continua acontecendo o que foi citado:

16 horas atrás, vangodp disse:

Ao ler uma das 4 flechas o primeiro valor retornado é 224, com isso você deveria saber que é preciso fazer uma nova leitura pois é na segunda leitura que ele retorna um dos valores que você indica(72, 75, 77, 80)

O programa tem que fazer a leitura duas vezes para poder executar o que se deseja, ou seja, está dando 2 loops para fazer uma coisa só. Pelo testes, o seu código está resultando no que deseja, mas, particularmente, entendo que existe um pequeno erro de lógica aí... pois deveria fazer cada tecla em um único loop.

Para "provar" isso, poderia inserir esse trecho no código:

    int cont=0; //usado para contar quantos loops o programa já deu
    do {
        system("cls");
        cont+=1;
        printf("Loop %d",cont);

 

 

Para corrigir isso, poderia fazer algo como sugerido por @vangodp.

 

16 horas atrás, vangodp disse:

if (ch == 0 || ch == 224)

 

Poderia ficar com algo assim:

        seta = getch();
        if (seta == 0 || seta == 224) //caso retorne um "pré-código" de setas
            seta = getch(); //ler novamente (para pegar a segunda parte)

Entende? ao pressionar uma seta, o método getch() primeiro retorna um código (224 ou 0)... ao tentar ler novamente uma tecla nova tecla, ele já retorna o código da tecla em si (obs.: a tecla é pressionada uma única vez, mas "consome" duas leituras).

 

Ai entra questão também das outras possibilidades... como do @cyer ou outras que podem existir...

 

 

 

2) CONDIÇÕES MUTUAMENTE EXCLUDENTES

Tecnicamente, para condições mutuamente excludentes em if, seria "necessário" o uso do else... pois se uma condição for verdadeira, necessariamente jamais poderia ser um outra... logo, não faz sentido verificar. Veja:

13 horas atrás, Code guy disse:

        if(seta==72)
            posicao++;
        if(seta==80)
            posicao--;

Se seta conter 72, JAMAIS, poderá também conter 80 também... logo, precisa do else antes do segundo if. Idem para os if da posicao.

 

Veja por exemplo o código do @cyer... só vai verificar as próximas, se as anteriores não forem verdadeiras.

 

 

 

3) "ORDEM DOS TRATORES"

Observe que no seu código você está usando ifs antes mesmo ter ter algum valor para seta, ou seja, está comparando algo que não foi inicializado. E não tem motivo para comparar... já que a comparação vem do fato da intenção de querer mudar, ou seja, do usuário ter pressionado uma tecla... se ninguém pressionou nada, por que verificar?

Resumindo: a leitura da seta deve vir antes dos if. Você colocou abaixo.

 

***

 

 

Por ai vai.

 

Att.

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

Muito obrigado pela resposta Simon Viegas! Como estou começando a programar em c++ ainda não tenho muita prática com programação e nem um professor para me auxiliar. Só uma observação:

Eu coloquei os if's antes do getch() para poder imprimir o menu antes de o usuário pressionar qualquer tecla.

       

       Vou levar os comentários em consideração e assim que puder eu posto o programa completo.

 

 

 

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

  • Membro VIP
1 hora atrás, Code guy disse:

Só uma observação:

Eu coloquei os if's antes do getch() para poder imprimir o menu antes de o usuário pressionar qualquer tecla.

Hum! Entendi. Mas a dica continua...:
 

6 horas atrás, Simon Viegas disse:

Resumindo: a leitura da seta deve vir antes dos if. Você colocou abaixo.

ou seja, deixa a parta da exibição em cima da leitura... em outras palavras: os if da seta ficam por último.

 

No aguardo.

Link para o comentário
Compartilhar em outros sites

Aqui está a solução final:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include<locale.h>
char nomeP[20][30],textoP[20][200][50];                      ///20(quantidade max de projetos),30(titulo)
int seta,posicao=0,quantP=0,linha=-1;
                                         ///CIMA = 72
                                         ///BAIXO = 80
void MenuposicaoS();
void Novo();
void Projeto();
//

int main()
{
    setlocale(LC_ALL,"portugese");
    while(1<2){
    MenuposicaoS();
    Novo();
    if(posicao>0)
    Projeto();
    }
    return 0;
}

//
void MenuposicaoS(){
    do{

    system("cls");



    printf("\n\n\t\tUORDI\n\n\t");

        if(posicao==0){
            printf("->Novo Projeto+\n");
        for(int i =0;i<=quantP;i++){
        printf("%s\n\t  ",nomeP[i]);
          }
        }

        else if(posicao>0){
            printf("  Novo Projeto+");
        for(int i =0;i<posicao;i++){
        printf("\n\t  %s",nomeP[i]);
          }
          printf("\n\t->");
        for(int i =posicao;i<=quantP;i++){
        printf("%s\n\t  ",nomeP[i]);
          }
        }


            seta = getch();                   ///comentario de: Simon Viegas (colocar o getch antes do if)
        if (seta == 0 || seta == 224)         ///<-comentario de: vangodp
            seta = getch();

    if(seta==80)
        posicao++;
    else if(seta==72)                        ///comentário de Simon Viegas e cyan(else antes do if)
        posicao--;

    if(posicao>quantP)
        posicao=0;
    else if(posicao<0)
        posicao=quantP;


    }while(seta!=13);
}
void Novo(){

    system("cls");

    if(posicao==0){
        quantP++;
        printf("\n\n\tTITULO:");
        gets(nomeP[quantP]);


        system("cls");

        do{
        linha++;

        gets(textoP[quantP][linha]);

        }while(textoP[quantP][linha][0]!='.');

    }

}
void Projeto(){

   system("cls");
        linha=-1;
        do{

            linha++;

        puts(textoP[posicao][linha]);

        }while(textoP[quantP][linha][0]!='.');

       getch();
}

OBS.: (Dentro do programa) para o programa entender que você acabou o texto basta digitar  "." (ponto final) no COMEÇO DE UMA LINHA.

 

Ps.: O programa ficou um pouco extenso, por isso vai ser díficil tanto de explicar quanto de entendê-lo mas vale a pena compilar para ver o resultado.

 

Este é um programa que armazena textos. (assim como o word)

 

Para compilar: Use windows, GNU GCC compiler.

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

  • Membro VIP

Olá @Code guy.

 

Vamos lá:

 

1) MODUS OPERANDI

14 horas atrás, Code guy disse:

OBS.: (Dentro do programa) para o programa entender que você acabou o texto basta digitar  "." (ponto final) no COMEÇO DE UMA LINHA.

O modo de utilizar o aplicativo deve está explícito no próprio aplicativo... ou melhor ainda, está estruturado para ser usado de modo intuitivo, ou seja, sem precisar que seja necessário explicar.

 

Resumindo: precisa revisar isso. Mas por hora, tomemos como "sabido" que precisa do ". " para finalizar. Essa questão não é tão importante agora.

 

 

 

2) TAMANHO DO ALGORITMO

14 horas atrás, Code guy disse:

Ps.: O programa ficou um pouco extenso, por isso vai ser difícil tanto de explicar quanto de entendê-lo mas vale a pena compilar para ver o resultado.

Não tem problema algum o tamanho... o mais importante que é que esteja coerente... em relação ao "entender", temos de cara o relatado no item 3. Outra forma interessante é inserir comentários nas linhas. No código do item 3, inserir um exemplo.

 

 

 

3) INDENTAÇÃO DE CÓDIGOS

É se suma importância que o código SEMPRE esteja indentando. Então, não existe desculpa, a medida que for alterando o código, já vai deixando indentado... beleza?

 

... abaixo segue um exemplo de como eu uso:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include<locale.h>
char nomeP[20][30],textoP[20][200][50]; ///20(quantidade max de projetos),30(titulo)
int seta,posicao=0,quantP=0,linha=-1;
                                        ///CIMA = 72
                                        ///BAIXO = 80
//void MenuposicaoS(); //acho interessante usar maiúsculas para separar os termos [SimonViegas]
void MenuPosicaoS();
void Novo();
void Projeto();

//
int main()
{
    setlocale(LC_ALL,"portugese");
    while (1<2) { //??? [SimonViegas]
        MenuPosicaoS();
        Novo();
        if(posicao>0)
            Projeto();
    }
    return 0;
}

//
void MenuPosicaoS() {  
    do {
        system("cls");
        printf("\n\n\t\tUORDI\n\n\t");
        if(posicao==0) {
            printf("->Novo Projeto+\n");
            for(int i =0;i<=quantP;i++) {
                printf("%s\n\t  ",nomeP[i]);
            }
        }
        else
            if(posicao>0) {
                printf("  Novo Projeto+");
                for(int i =0;i<posicao;i++) {
                    printf("\n\t  %s",nomeP[i]);
                }
                printf("\n\t->");
                for(int i =posicao;i<=quantP;i++) {
                    printf("%s\n\t  ",nomeP[i]);
                }
            }
            
        seta = getch();                ///ler a tecla pressionada pelo usuário 
        if (seta == 0 || seta == 224)  ///verifica se foi retornado um pré-código referente as setas (as setas geram 2 códigos, e precisam ser lidos 2 vezes)
            seta = getch(); ///"ler" novamente para coletar o código da tecla em si (pois as setas geram antes um pré-código, como citado anteriormente)
        
        if(seta==80) ///se tecla BAIXO
            posicao++;
        else if(seta==72) ///se tecla CIMA
            posicao--;

        if(posicao>quantP)
            posicao=0;
        else if(posicao<0)
            posicao=quantP;
    } while(seta!=13);
}
void Novo(){
    system("cls");
    if(posicao==0) {
        quantP++;
        printf("\n\n\tTITULO:");
        gets(nomeP[quantP]);
        system("cls");
        do {
            linha++;   
            gets(textoP[quantP][linha]);
        }while(textoP[quantP][linha][0]!='.');
    }
}

void Projeto(){
    system("cls");
    linha=-1;
    do {
        linha++;
        puts(textoP[posicao][linha]);
    } while(textoP[quantP][linha][0]!='.');
    getch();
}

Compare um código com o outro. Qualquer dúvida é só perguntar. Mas se atente a isso. O código tem que está indentado sempre!!!

 

 

4) RESTRUTURAÇÃO DA LÓGICA

 

14 horas atrás, Code guy disse:

        while (1<2) { //??? [SimonViegas]
            MenuPosicaoS();
            Novo();
            if(posicao>0)
                Projeto();
        }

Inicialmente não entendi por que no Novo() você deixou a verificação da posicao dentro do método, e para o Projeto() deixou fora, ou seja, ou ambos ficam dentro, ou ambos ficam fora... não fica interessante tratar de duas formas diferente algo tão próximo.

 

Então, pelo que eu entendi, você deveria poderia usar um conjunto de if ou case para identificar a posição e usar o item que for correspondente, ou seja, o método MenuPosicaoS() vai tratar da animação do menu e a escolha do item... ai o if (ou case) verifica qual o valor da posição e invoca o método correspondente, algo como:

MenuPosicaoS();
se (posicao=0) então
  Novo()
senão
  Projeto();

 

 

 

5) CONDIÇÃO DE PARADA

Não consegui entender como finalizar o programa... mas resumidamente você poderia inserir no "Menu". Algo como:


                UORDI

        ->Novo Projeto+
          Sair

Ai, no gancho do item 4, ficaria algo como:

MenuPosicaoS();
se (posicao=0) então
  Novo()
senão
  se (posicao=ULTIMAPOSICAO) então  //ou alguma forma que identifique que foi "sair"
  	//faz algo para sair... como mudar uma flag que está controlando o while
  senão
    Projeto();

Ou seja, ou "insere um novo", ou "sai do programa", ou "exibe os dados de um projeto já criado".

 

Quando tiver projetos, ficaria como como:

                UORDI

          Novo Projeto+
          Meu Primeiro Projeto
        ->Dicas de implementação de algoritmos
          Lista de convidados pro baba
          Sair

 

Talvez, para facilitar a implementação do Sair, poderia colocar em cima. Ai 0 seria sair, 1 novo projeto, e o restante seria listar...

 

 

***

 

Por ai vai.

 

No aguardo.

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

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!