Làm cách nào để xử lý đầu vào trong C mà không tạm dừng vòng lặp chính?
Tôi muốn chương trình C của mình cập nhật bảng điều khiển mỗi giây và nó hoạt động tốt cho đến khi tôi cố gắng xử lý đầu vào. Bây giờ chương trình tạm dừng vì nó đợi một đầu vào từ người dùng. Tôi có thể làm cái này như thế nào?
while(true) {
ShowConsole(); //Show
Sleep(1000); //Wait
scanf("%s",&a) //Handle Input
Update();
ClearScreen(); //Clear
}
Trả lời
Tôi đã tự do để thử và giải quyết vấn đề này.
Chỉ dựa trên nội dung câu hỏi, không rõ bạn đang cố gắng làm trò gì, vì vậy tôi đã sử dụng cách tiếp cận của một loại trò chơi rắn , nơi con rắn sẽ di chuyển, bất kể người chơi đang làm gì (hoặc không làm) .
Tôi đã sử dụng Sleepcho tốc độ bỏ phiếu đầu vào và tỷ lệ vẽ lại, và _kbhit()để có thể đọc một ký tự, và clock_t/ clock()để cập nhật các trò chơi một lần mỗi giây.
Bây giờ tôi không phải là một clập trình viên, vì vậy tôi không biết liệu cmã này có "tao nhã" hay không (có thể là không), nhưng nó đã hoạt động trên máy của tôi (Windows, Visual Studio).
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <ctype.h>
#include <windows.h>
typedef int BOOL;
#define FALSE ((int)0)
#define TRUE ((int)1)
void ClearScreen()
{
// code here that clears the screen, see https://stackoverflow.com/a/42500322
}
int main( void )
{
BOOL run = TRUE;
clock_t lastTickClock = clock();
int position = 0;
char registeredCommand = 'd'; // Command that will be effective at the next game tick.
while ( run )
{
char currentCharIfAny = 0; // The char that is read this loop.
if ( _kbhit() )
currentCharIfAny = _getch();
if ( currentCharIfAny == 'a' || currentCharIfAny == 'd' )
registeredCommand = currentCharIfAny; // We only respond to 'a' or 'd'.
clock_t newClock = clock();
if ( ( newClock - lastTickClock ) > CLOCKS_PER_SEC )
{
// This is the command handling/the game tick
if ( registeredCommand == 'a' )
position = max( --position, 0 );
else if ( registeredCommand == 'd' )
position = min( ++position, 24 );
lastTickClock = newClock;
}
char buffer[1024];
buffer[0] = 0;
for ( int i = 0; i < position; ++i )
strcat_s( buffer, 1024, " " );
strcat_s( buffer, 1024, "_\n" ); // This underscore represents our "agent" or "game token" or "paddle".
// The following is only for debugging purpose; it prints the character we're currently handling.
if ( currentCharIfAny >= 'a' && currentCharIfAny <= 'z' )
{
char lbuff[2]; lbuff[0] = 0;
sprintf_s( lbuff, 2, "%c", currentCharIfAny );
strcat_s( buffer, 1024, lbuff );
}
ClearScreen();
printf( "%s\n", buffer );
Sleep( 1000 / 60 );
if ( currentCharIfAny == 'q' )
run = FALSE;
}
printf( "\ndone. press a key to quit." );
_getch();
return 0;
}
Một số điều cần lưu ý:
- có lẽ có những cách khác (tốt hơn) để đạt được điều này: hiện tại, khi tôi làm mới (ClearScreen), màn hình "nhấp nháy" một chút.
- trên Windows, hệ điều hành sẽ "điều chỉnh" tốc độ lặp lại của ký tự mà nó gửi đến các ứng dụng, vì vậy, khi bạn nhấn d, chương trình sẽ hiển thị rằng bạn đang nhấn d, sau đó nó sẽ hiển thị rằng bạn không nhấn phím nào, sau đó nó sẽ hiển thị bạn đang đánh dmột lần nữa, cho đến khi bạn nhả phím.
- như triển khai của riêng bạn, nó không di động do bản chất của các chức năng được sử dụng.
Mặc dù tôi phải sử dụng mã không di động nhưng tôi đã có thể làm việc mà không cần thư viện của bên thứ ba. Ngoài ra, hàm _kbhit () làm chậm bộ đệm nên bạn không cần đợi 1 giây để nhập chuỗi đầy đủ. Tuy nhiên, chuỗi đã viết đã bị cắt nếu nó không được viết trong một giây. Vì vậy, tôi cũng đã hiển thị nó trong hàm ShowConsole ().
Lưu ý: Đây là mã không độc lập, không di động. Hoạt động trong hệ điều hành của tôi (Windows).
char key;
if(_kbhit()){
key = _getch();
if(key == 13){ //If Enter key is pressed
HandleInput(moveInput); //handle the input string
memset(moveInput, 0, 6); //clear input string
moveIndex=0; //reset string index to 0
}
moveInput[moveIndex] = key; //If any other key is pressed, add the hit character to string input
moveIndex++;
}
Trong hàm ShowConsole ():
ShowConsole(){
.
.
.
printf("%s", moveInput); // At the end of showing the graphics, also show the input that is being written.
}