在不按Enter的情况下读入命令提示符输入 [英] Read in command prompt input without pressing enter
问题描述
我正在尝试在Windows命令提示符下的C语言中编写一个程序,可以用来练习触摸打字。为此,我要让程序提示输入字母,并希望在输入字母后立即记录该字母是否正确,并在退出并告诉我我的密码之前重复该过程预定的次数。时间和准确性。
通过在每个字母之间按Enter使其工作很容易,但是我觉得它没有像我不必按Enter那样有用。我在大学里做了一个项目,该项目具有类似的组件,但是该项目是在Linux中使用C ++进行的。我不想只为该程序设置整个虚拟盒子。
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);
如果我可以使用C在Windows的命令提示符下制作具有相同功能的东西,那就太好了,但是人们一直说在C语言中不可能有可移植的解决方案。我不在乎它是否只能在此PC上运行,我只是希望它能够运行。
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.
我想到的另一个想法是找到一个函数,该函数可以反复刷新键盘缓冲区,但仍然可以看到刷新的内容。然后,只要足够快,反正最多只能有一个字符,这个功能存在吗?显然,可以使用conio.h库完成此操作,但这据说是从DOS来的,并且不能在现代系统上运行(拒绝在我的系统上运行)。
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;
}
推荐答案
这?基本上,您将控制台重置为无缓冲,即读取时没有换行,也没有回声,从而防止了字符的出现。要回显,请将SetConsoleMode更改为ENABLE_ECHO_INPUT而不是0。一旦您希望正常输入,就重置控制台模式,这是最后一行。
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;
}
这篇关于在不按Enter的情况下读入命令提示符输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!