Ir ao conteúdo
  • Cadastre-se

C++ Como pausar o meu programa na tecla desejada ?


isvkt

Posts recomendados

@isvkt    

o HexadecimaL  0x31  é o decimal  49 que é o código ASCII do caractere número 1 e Tecla 1
o HexadecimaL  0x32  é o decimal  50 que é o código ASCII do caractere número 2 e Tecla 2
o HexadecimaL  0x33  é o decimal  51 que é o código ASCII do caractere número 3 e Tecla 3
o HexadecimaL  0x34  é o decimal  52 que é o código ASCII do caractere número 4 e Tecla 4
assim você pode usar uma função da biblioteca conio.h

#include <conio.h>
tecla = getch(); // le o teclado sem precisar digitar enter

   poste o código que você já fez sobre esse exercício , para vermos como está e em que podemos ajudar  .

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

8 horas atrás, isvkt disse:

Gostaria de pausar o meu programa na tecla 0x32, 0x33, 0x34 e fazer voltar a funcionar na tecla 0x31

 

Sugiro evitar números mágicos e usar constantes. Seu programa não fica melhor por não usar '2', '3' e '4'.

 

E parar o programa seria o que? E o programa seria o que?

 

Imaginando que fosse um loop qualquer, como uma bolinha atravessando a tela e controlada por essas ou outras teclas, e que usa Windows, o normal é usar SetConsoleMode e desligar o tal line input e o ECHO, para ler tecla por tecla sem echo. E aí usar ReadConsole() para ler o que tiver para ler e reagir de acordo. Já postei exemplos aqui, pode pesquisar no próprio forum. Esta tudo documentado onde esperado: https://docs.microsoft.com/pt-br/windows/console/console-reference

 

image.png.5841bcf1c86fe44fb3e0c696635748c1.png

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

  • Membro VIP
14 horas atrás, devair1010 disse:

função da biblioteca conio.h

#include <conio.h>
tecla = getch(); // le o teclado sem precisar digitar enter

Foi uma primeira coisa que pensei . Tentei rodar isso abaixo num compilador on line e não deu muito certo... A função ecoa o que digito mas não reconhece a tecla. Penso que é alguma restrição/segurança ou do gênero do compilador online

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

int main() {
    // Write C code here
    char tecla;
    printf("Hello world");
    for (;;)
    {
    tecla = getch(); // le o teclado sem precisar digitar enter
    if (tecla=='1') {printf("%d",tecla); printf("ok");}
    }
    return 0;
}

 

qualquer momento tento no compilador local algo como

for (;;)
{
while ((tecla>=0x32)&&(tecla<=0x34))
	{                                    
	tecla=getch();
	faca_o_que_deve_ser_feito();//...volte sempre!
	}
while (tecla!=0x31)
	{
	tecla=getch();
	faca_algo_enquanto_espera();//...volte sempre!
	}  
}                                   

 

...pensando melhor...

for (;;)
{
for(;;)
	{                                    
	tecla=getch();
	if ((tecla<=0x32)&&(tecla>=0x34)) break; 
	faca_o_que_deve_ser_feito();//...volte sempre!
	}
for(;;)
	{
	tecla=getch();
	if (tecla==0x31) break;
	faca_algo_enquanto_espera();//...volte sempre!
	}  
}                                   

..sei lá se melhorou 🤪

 

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

34 minutos atrás, .if disse:

Foi uma primeira coisa que pensei . Tentei rodar isso abaixo num compilador on line e não deu muito certo... A função ecoa o que digito mas não reconhece a tecla. Penso que é alguma restrição/segurança ou do gênero do compilador online

Apenas não teve ter conio.h, dos anos 80. Se tem a fonte apenas inclua no programa.

 

A console do Windows num compilador remoto é algo difícil de imaginar.

 

Se for o gcc para Linux se faz a mesma coisa, mas usando ioctl e fread Use man ioctl e verá as estruturas que deve usar.

 

No Windows sugiro fazer como eu disse, a partir da documentação que eu mostrei. e usar ReadConsole. 

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

1 hora atrás, .if disse:

Foi uma primeira coisa que pensei . Tentei rodar isso abaixo num compilador on line e não deu muito certo... A função ecoa o que digito mas não reconhece a tecla.

O problema é que a conio.h não faz parte da biblioteca padrão do C, e suas poucas funções podem ser implementadas em poucas linhas em Windows ou Linux.

  • ENABLE_ECHO_INPUT (Windows): Os caracteres lidos pela função ReadFile ou ReadConsole são gravados no buffer de tela ativo à medida que são inseridos no console. Esse modo poderá ser usado somente se o modo ENABLE_LINE_INPUT também estiver habilitado.
  • ENABLE_LINE_INPUT (Windows): A função ReadFile ou ReadConsole será retornada somente quando um caractere de retorno de carro for lido. Se esse modo estiver desabilitado, as funções serão retornadas quando um ou mais caracteres estiverem disponíveis.
  • ECHO (Linux): Ecoar caracteres de entrada.
  • ICANON (Linux):  A entrada é disponibilizada linha por linha. Uma linha de entrada está disponível quando um dos delimitadores de linha é digitado (NL, EOL, EOL2; ou EOF no início da linha). Exceto no caso de EOF, o delimitador de linha é incluído no buffer retornado por read(). No modo não canônico, a entrada está disponível imediatamente (sem que o usuário precise digitar um caractere delimitador de linha), nenhum processamento de entrada é executado e a edição de linha é desabilitada. O buffer de leitura só aceitará 4095 caracteres; isso fornece o espaço necessário para um caractere de nova linha se o modo de entrada for alterado para canônico.

Usando SetConsoleMode() em Windows e tcsetattr() em Linux, conseguimos desligar esses modos.

Windows:

int getch(void)
{
    DWORD mode;
    int total = 0;
    int c = 0;

    HANDLE h = GetStdHandle(STD_INPUT_HANDLE);

    if(h == NULL) {
        // GetStdHandle() falhou
        return 0;
    }

    // Salvando
    GetConsoleMode(h, &mode);
    // Alterando
    SetConsoleMode(h, mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT));

    ReadConsole(h, &c, 1, (LPDWORD)&total, NULL);

    // Restaurando
    SetConsoleMode(h, mode);

    if(total > 0) {
        if(c == '\r') c = '\n';
        return c;
    } else {
        // não leu nada
        return 0;
    }
}

Linux:

int getch(void)
{
    struct termios oldMode, newMode;
    int ch;
    
    // Salvando
    tcgetattr(0, &oldMode);
    
    newMode = oldMode;
    newMode.c_lflag &= ~(ICANON | ECHO);

    // Alterando
    tcsetattr(0, TCSANOW, &newMode);
    
    ch = getchar();
    
    // Restaurando
    tcsetattr(0, TCSANOW, &oldMode);
    
    return ch;
}

 

1 hora atrás, .if disse:

A função ecoa o que digito mas não reconhece a tecla. Penso que é alguma restrição/segurança ou do gênero do compilador online

Dá uma olhada aqui. :D

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

  • Membro VIP
5 horas atrás, Lucca Rodrigues disse:

suas poucas funções podem ser implementadas em poucas linhas em Windows ou Linux.

No meu micromundo tem 'ligeiramente' menos linhas:

char getch()
{
while((!RCIF)&&(int tmout--));//aguarda flag de recepção com timeout
return RCREG; //registro de recepção
}

ou nem...

char tecla;
void interrupt serial //interrompe quando RCIF=1 .. algo como ReCeption Interrupt Flag
{
tecla=RCREG; //registro de recepção
}

Como o garoto não falou qual seu nível, algo da 'ralé' pode não lhe ser totalmente inútil... 😜

 

edit

inseri tmout pra compatibilizar mais

Ah e edit de novo caso o garoto pense que dar crtl-c ctrl-v no que postei vai resolver.. aquilo apesar de ser c,  é pro mundo dos microcontroladores mais especificamente pra família pic16fxxx ok?

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

what would it look like in my code?
 

    while (true) {

        for(int i = 0; i < 5; ++i) {
            if (GetAsyncKeyState(gun_key[i]) && (gun != guns[i])) {
                gun = guns[i];

                system("cls");

                cout << "Weapon:\t" << gun->name << "\nShots:\t" << gun->len << "\nVelocity:\t" << gun->rpm << "\n\n\n";

                gun_delay = GetTime(gun->rpm);
                gun_index = 0;

                break;
            }
        }

        if (GetAsyncKeyState(VK_LBUTTON) < 0) {
            if (!is_mouse_down) {
                is_mouse_down = true;
                if (gun != nullptr)
                    gun_index = 0;
            }
            if (gun != nullptr  && gun_index != gun->len) {
                mouse_event(MOUSEEVENTF_MOVE, long(gun->pattner[gun_index][0] * K), long(gun->pattner[gun_index][1] * K), 0, 0);
                ++gun_index;
                Sleep(gun_delay);
                continue;
            }
        }
        else    
            is_mouse_down = false;

        Sleep(150);
    }

    return 0;
}

 

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

@isvkt

Você não postou o código completo e não sabemos onde vai implementar essa lógica, e de qualquer forma ninguém vai implementar isso no seu código, esse é seu trabalho.

//

You didn't post the complete code and we don't know where you're going to implement this logic in it, anyway, no one is going to implement it in your code, that's your job.

 

Em 17/01/2022 às 14:32, Lucca Rodrigues disse:

Talvez possa usar a WaitForSingleObject() se for algo simples.

Veja:

// Identificador para a stdin
HANDLE console = GetStdHandle(STD_INPUT_HANDLE);

printf("<Esperando teclar 2, 3 ou 4>\n");
while(1)
{
    FlushConsoleInputBuffer(console);
    if(WaitForSingleObject(console, 1000) == WAIT_OBJECT_0)
    {
        // Houve um evento de entrada
        break;
    }
    // Etc
}

WaitForSingleObject() no código aguarda um evento de entrada por 1 segundo.

Como pode tratar esse evento de entrada? Queremos que seja um evento do teclado, mais precisamente as teclas 2, 3 ou 4. Pode usar PeekConsoleInput().

Outra opção seria essa tal GetAsyncKeyState() que como já disse em outro tópico, é problemática.

//

WaitForSingleObject() in the code above waits for an input event for 1 second.

How can you handle this input event? We want it to be a keyboard event, more precisely keys 2, 3 or 4. You can use PeekConsoleInput().

Another option would be GetAsyncKeyState() which, as I said in your other topic, is problematic.

Ok, considerando que foi detectado um evento na entrada, foi um evento de pressionamento de tecla e essa tecla está entre 2 e 4, o que fazer? Pode usar getch():

//

Okay, considering an input event was detected, it was a key event and that key is between 2 and 4, what to do next? You can use getch():

// ...
printf("<Esperando teclar 1>\n");
while (getch() != '1');
break;
// ...

Enquanto não for pressionada a tecla 1, o loop persiste.

Postei os códigos para Windows e Linux da getch() um pouco acima.

//

As long as key 1 is not pressed, the loop persists.

I posted getch() codes for Windows and Linux a little above.

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