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:  
Code guy

C++ RESOLVIDO Como capturar o valor das setas ?

Recommended Posts

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

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tenta com a função kbhit

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

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

Mas pode deixar, ja resolvi o programa. 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

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

Compartilhar este post


Link para o post
Compartilhar em outros sites

Provavelmente o que deve lhe estar surpreendendo é que ao pulsar as teclas das flechas o valor de retorno sempre seja 224:D. Correto?

 

Saiba que getch é uma "funçãozinha" meia especial, ela não retorna um só valor, se não que retorna 2.

Aqui esta a prova:

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

int main ()
{
    int ch;

    ch = _getch();
    printf("%d", ch);

    if (ch == 224)
        printf (", %d", _getch ());

    return (0);
}

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). Por que acontece isso? Isso é assim para poder diferenciar se se trata das flechas normais ou das flechas do teclado numérico, já .que se tratar das flechas do teclado numérico o programa retorna 0 primeiro e depois(72, 75, 77, 80). Pode ser comprovado isso? Sim claro! De uma olhada neste programa:
 

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

int main ()
{
    int ch;

    while ((ch = _getch()) != 27) /* 27 = Esc key */
    {
        printf("%d", ch);
        if (ch == 0 || ch == 224)
            printf (", %d", _getch ());
        printf("\n");
    }

    printf("ESC %d\n", ch);

    return (0);
}

Este programa vai lhe dar todos os códigos das teclas que forem pulsadas. Recorde que algumas são uma combinação de 2 valores, se getche por exemplo retornar primeiro um 224, você precisa fazer uma nova chamada a getche, pois o seguinte valor retornado se trata do código da tecla, e igual acontece se getche retornar 0, deverá ser invocado novamente para saber de qual tecla se trata, por isso esse programa é muito útil.

Espero que com isso tenha ficado claro.

Editado por vangodp
  • Curtir 2
  • Obrigado 1

Compartilhar este post


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

Editado por Code guy
  • Curtir 1

Compartilhar este post


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

Compartilhar este post


Link para o post
Compartilhar em outros sites

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 3

Compartilhar este post


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

Compartilhar este post


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

Compartilhar este post


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

Editado por Code guy
  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

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 2

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

×