Read in command prompt input without pressing enter

你。 提交于 2020-07-10 03:17:58

问题


I am trying to write a program in C on windows command prompt that I can use to practice touch typing. I want to do this by having the program prompt for a letter and as soon as I have entered a letter, I want it to record whether or not that letter was correct and repeat the process a predefined number of times before exiting and telling me my time and accuracy. Making it work by pressing enter between each letter is easy enough, but I feel like it wont be as helpful as it would be if I didn't have to press enter. I did a project at university that had a similar component, but that was in linux and using C++. I don't want to have to do the whole set up a virtual box etc just for this program.

//The linux program included something like this:
//collecting original structure formate
tcgetattr(STDIN_FILENO, &normTerm); 
//assigning the original structure format to the temporary structure format
tempTerm = normTerm; 
//making the temporary structure format into raw form
cfmakeraw(&tempTerm); 
//setting the structure format to the raw form
tcsetattr(STDIN_FILENO, TCSANOW, &tempTerm);

//cfmakeraw() turns the structure at the address into the raw terminal attributes desired

//insert function that asks the user to input their password with all the flags changed so that you can't read what you have typed

    tcsetattr(STDIN_FILENO, TCSANOW, &normTerm);

If I could make something that had the same functionality on command prompt in windows using C that would be great, but people keep saying "a portable solution is not possible in C". I don't mind if it only works on this PC, I just want it to work.

Another idea I thought of was to find a function that flushes the keyboard buffer repeatedly, but can still see what it has flushed. Then, so long as it is fast enough, it will only have a maximum of one character in it anyway.Does this function exist? Apparently it can be done with the conio.h library, but that is said to be from DOS and doesn't work on modern systems(refuses to work on mine).

The code I have written so far is below
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <termios.h>


void main()
{
    //seeding random number generator
    srand(time(NULL));

    //char variables for actual and desired user input
    char input = 0;
    char testCharacter = 1;

    //float variables for calculating accuracy
    float countCorrect = 0;
    float countTotal = 5;
    float accuracy = 0;

    //temp variables for program operations
    int iterations = int(countTotal);
    int characterIndex = 0; 

    long startTime = time(NULL);    

    while(iterations>0)
    {
        //I am aware of the asymmetry of this, I might get around to fixing it latter
        characterIndex = (rand() %52) + 1;
        //printf("Value returned by random num gen is %d\n", characterIndex);

        //The following is messy because I don't use all the ascii characters
        //I could also probably just write a number to the char variable and then treat it as a letter to do away with the switch case statements, but I will look into that latter
        characterIndex += 64;
        if(characterIndex >= 91)
        {
            characterIndex = characterIndex + 7;
        }

        //switch case statements go here

        printf("Please type the letter below:\n%c\n", testCharacter);

        //%$&$&%*&)()*)&^%&$^&(*)_(*^&$%#^&$^%^*(&)*)(_)_*&^$%^#$^$&*(&)*(*&(^
        //This is the bit I want to modify to not require the enter key
        scanf("%c", &input);
        getchar();
        //something like 
        while(keyboard buffer is empty)
        {
        }
        flush keyboard into &input
        //maybe I could use a shell command to manually press enter whenever the keyboard buffer isn't empty???
        //(*()%&$^#$%$&^(*)*&(^$%#%$&^(*)*)&^($%&&^*(&)&*&(^$*(&)*&^($&(***&^$%*^&

        printf("\n");
        //keeps track of correct answers
        if(input == testCharacter)
        {
            countCorrect++;
            //printf("The letter %c was typed and was correct\n", input);           
        }
        else
        {
            //printf("The letter %c was typed and was incorrect\n", input);
        }

        iterations = iterations - 1;
    }

    //calculates time difference in seconds
    long timeDifference = time(NULL) - startTime;
    //calculates accuracy
    accuracy = 100.0 * (countCorrect / countTotal);
    printf("Accuracy achieve was %f%\nThe time taken was %d seconds\nPress any key to continue: ", accuracy, timeDifference);

    scanf("%c", &input);    

    return 0;
}

回答1:


How's this? Basically, you reset the console to unbuffered, which reads without linefeed, and no echo, which prevents the character from appearing. To echo, change the SetConsoleMode to ENABLE_ECHO_INPUT instead of 0. Once you'd like normal input, you reset console mode, which is the last line.

#include <windows.h>
#include <stdio.h>
int main()
{
    DWORD        mode;
    HANDLE       hstdin;

    hstdin = GetStdHandle( STD_INPUT_HANDLE );

    GetConsoleMode( hstdin, &mode );
    SetConsoleMode( hstdin, mode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));

    char result;

    printf("Press x to exit");

    while(1){
        result = getchar();
        if(result == 'x')
            break;
    }
    SetConsoleMode(hstdin, mode);
    return 0;
}


来源:https://stackoverflow.com/questions/27653016/read-in-command-prompt-input-without-pressing-enter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!