1.这是用windows api写的程序。所以要求是纯c的话就没有办法了2.其中定时用了两种方法。一种是用取消息。另一种是延时队列。这里只使用了取消息的方法。延时队列由于我机器上是,CreateTimerQueue在本人机器上无法使用,需要新的sdk,所以没有加以验证,但取消息的方式是可行的。3.稍稍验证了下,基本满足要求。-------------------------------------------程序如下:// : Defines the entry point for the console application.//#include ""#include <>#include <>typedef struct _st_time{ int hour; int min; int sec;}ST_TIME;ST_TIME g_Time; // The struct contain the hour,min and g_hStdout; // WORD g_cxCenter, g_cyCenter; // Center of the g_DoneEvent; // The program could be g_ThreadTerminated; // The Thread should be terminated.#define SECOND_CIRCLE 60#define MINUTE_CIRCLE 60#define HOUR_CIRCLE 24void TimeIncreaseSecond(ST_TIME & st){ ++; if ( >= SECOND_CIRCLE) { -= SECOND_CIRCLE; ; if ( >= MINUTE_CIRCLE) { -= MINUTE_CIRCLE; ; if ( >= HOUR_CIRCLE) { -= HOUR_CIRCLE; } } } }void PrintTimeToScreen(HANDLE hStdout, short cxCenter, short cyCenter, ST_TIME st){ char buf[64] = {0}; COORD crdPos; // make it format to output. sprintf (buf, "%02d:%02d:%02d", , , ); = cxCenter - 4; = cyCenter; SetConsoleCursorPosition(hStdout, crdPos); printf(buf); }#ifdef USE_TIMERQUEUE // if we use the timer queue function.// Its procdure is in CALLBACK TimerRoutine (LPVOID lpParam, BOOL TimerOrWaitFired) { if (lpParam == NULL) { printf ("NULL parameters.\n"); } else { ST_TIME *st = (ST_TIME *)lpParam; TimeIncreaseSecond(st); PrintTimeToScreen(g_hStdout, g_cxCenter, g_cyCenter, *st); }}#elseDWORD WINAPI TimerThreadProc(LPVOID lpParam){#define ID_TIMER_SECOND 1 MSG msg; BOOL ret; ST_TIME *st = (ST_TIME *)lpParam; SetTimer(NULL, ID_TIMER_SECOND, 1000, NULL); PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); while (!g_ThreadTerminated && (ret = GetMessage (&msg, NULL, 0, 0)) != 0) { if (ret == -1) { //process fatal event. } else if ( == WM_TIMER) { TimeIncreaseSecond(*st); PrintTimeToScreen(g_hStdout, g_cxCenter, g_cyCenter, *st); } else { TranslateMessage (&msg); DispatchMessage (&msg); } } return 1;}#endif// If the ctrl+break combined key pressed. call this function.// It set the g_DoneEvent. this terminate the WINAPI CtrlHandler(DWORD fdwCtrlType) { switch (fdwCtrlType) { case CTRL_BREAK_EVENT: // Terminate the program. printf ("Terminate.\n"); SetEvent(g_DoneEvent); return TRUE; default: return FALSE; } } BOOL InitApplication(){ // Get the stdin and stdout handle. HANDLE hStdIn; hStdIn = GetStdHandle(STD_INPUT_HANDLE); if (hStdIn == INVALID_HANDLE_VALUE) return FALSE; g_hStdout = GetStdHandle(STD_OUTPUT_HANDLE); // Set the mode, make the input echo. DWORD fOldMode; GetConsoleMode(hStdIn, &fOldMode); fOldMode |= ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT; SetConsoleMode(hStdIn, fOldMode); // Set the window buffer. // make a line 40 columns. CONSOLE_SCREEN_BUFFER_INFO csbiInfo; GetConsoleScreenBufferInfo(g_hStdout, &csbiInfo); = 40; // get the center point. g_cxCenter = / 2; g_cyCenter = / 2; // Set the window. SetConsoleWindowInfo(g_hStdout, TRUE, &); return TRUE;}BOOL PrintTheInitalStateAndGetInput(HANDLE hStdout, WORD cxCenter, WORD cyCenter, ST_TIME & time){#define GAPS_LEFT_COLON (-2)#define GAPS_RIGHT_COLON (1)#define GAPS_LEFT_UNDERLINE_START (-4)#define GAPS_MIDDLE_UNDERLINE_START (-1)#define GAPS_RIGHT_UNDERLINE_START (2) // __:__:__ // So the left ":" center -2 // so the right ":" center + 1 // so the left "_" center - 4; // so the lfet "_" center - 1; // so the right "_" center + 2; COORD crdPos; = cxCenter + GAPS_LEFT_COLON; = cyCenter; SetConsoleCursorPosition(hStdout, crdPos); printf (":"); = cxCenter + GAPS_RIGHT_COLON; SetConsoleCursorPosition(hStdout, crdPos); printf (":"); = cxCenter + GAPS_LEFT_UNDERLINE_START; SetConsoleCursorPosition(hStdout, crdPos); scanf ("%d", &); = cxCenter + GAPS_MIDDLE_UNDERLINE_START; SetConsoleCursorPosition(hStdout, crdPos); scanf ("%d", &); = cxCenter + GAPS_RIGHT_UNDERLINE_START; SetConsoleCursorPosition(hStdout, crdPos); scanf ("%d", &); if ( < 0 || > HOUR_CIRCLE || < 0 || > MINUTE_CIRCLE || < 0 || > SECOND_CIRCLE) return FALSE; return TRUE;}int main(int argc, char* argv[]){ InitApplication(); PrintTheInitalStateAndGetInput(g_hStdout, g_cxCenter, g_cyCenter, g_Time); // create a event to tell the program to terminate. g_DoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);#ifdef USE_TIMERQUEUE HANDLE hTimerQueue, hTimer; hTimerQueue = CreateTimerQueue(); if (!CreateTimerQueueTimer(&hTimer, hTimerQueue, TimerRoutine, &g_Time, 1000, 0, 0)) { printf("CreateTimerQueueTimer failed (%d)\\n", GetLastError()); return 3; }#else // create the thread. HANDLE hThreadTimer; DWORD dwThreadId; g_ThreadTerminated = FALSE; hThreadTimer = CreateThread(NULL, 0, TimerThreadProc, &g_Time, 0, &dwThreadId); if (hThreadTimer == NULL) { } #endif SetConsoleCtrlHandler(CtrlHandler, TRUE); if (WaitForSingleObject(g_DoneEvent, INFINITE) != WAIT_OBJECT_0) printf("WaitForSingleObject failed (%d)\\n", GetLastError()); #ifdef USE_TIMERQUEUE if (!DeleteTimerQueue(hTimerQueue)) printf("DeleteTimerQueue failed(%d) \\n", GetLastError()); #else g_ThreadTerminated = TRUE; if (WaitForSingleObject(hThreadTimer, INFINITE) != WAIT_OBJECT_0) printf("WaitForSingleObject failed (%d)\\n", GetLastError());#endif return 0;}--------------------------------------------下面是纯c的。有几个问题:函数在turboc中没有办法使用,不知道是什么问题,而borland c就可以。2.无论怎么设置,自己的ctrlbreak函数在上述两个环境中都不能被调用,非常遗憾。所以不能够优雅的退出。只能按两次ctrlbreak。下面是程序。------------------------------------------#include <>#include <>#include <>#include <>#include <>#define ABORT 0int jump_out_loop = -1;int jump_out(void){ jump_out_loop = 1; printf("Abort ..\n"); return ABORT;}int main(void){ struct text_info ti; int center_x, center_y; int hour, min, sec; char str_out[64] = {0}; clrscr(); /*textmode(BW40);*/ /*textmode在turbo c下设置会出问题*/ gettextinfo(&ti); center_x = / 2; center_y = / 2; gotoxy(center_x - 4, center_y); cprintf(" : : "); gotoxy(center_x - 4, center_y); cscanf("%d", &hour); gotoxy(center_x - 1, center_y); cscanf("%d", &min); gotoxy(center_x + 2, center_y); cscanf("%d", &sec); /* check input valid or not */ {} setcbrk(1); ctrlbrk(jump_out); /*jump_out没有起到作用,实在不好意思.*/ /* if (getcbrk()) printf("crtl break is on\n"); else printf("is off\n"); */ while (1) { delay(1000); sec++; if (sec >= 60) { sec -= 60; min++; if (min >= 60) { min -= 60; hour++; if (hour >= 24) { hour -= 24; } } } sprintf(str_out, "%02d:%02d:%02d", hour, min, sec); gotoxy(center_x - 4, center_y); cprintf(str_out); } /* getch();*/ return 0;}