1.这是用windows api写的程序。所以要求是纯c的话就没有办法了
2.其中定时用了两种方法。一种是用取消息。另一种是延时队列。这里只使用了取消息的方法。延时队列由于我机器上是vc6.0,CreateTimerQueue在本人机器上无法使用,需要新的sdk,所以没有加以验证,但取消息的方式是可行的。
3.稍稍验证了下,基本满足要求。
-------------------------------------------
程序如下:
// DigitalClock.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <winbase.h>
typedef struct _st_time{
int hour;
int min;
int sec;
}ST_TIME;
ST_TIME g_Time; // The struct contain the hour,min and sec.
HANDLE g_hStdout; //
WORD g_cxCenter, g_cyCenter; // Center of the screen.
HANDLE g_DoneEvent; // The program could be over.
BOOL g_ThreadTerminated; // The Thread should be terminated.
#define SECOND_CIRCLE 60
#define MINUTE_CIRCLE 60
#define HOUR_CIRCLE 24
void TimeIncreaseSecond(ST_TIME & st)
{
st.sec ++;
if (st.sec >= SECOND_CIRCLE)
{
st.sec -= SECOND_CIRCLE;
st.min++;
if (st.min >= MINUTE_CIRCLE)
{
st.min -= MINUTE_CIRCLE;
st.hour++;
if (st.hour >= HOUR_CIRCLE)
{
st.hour -= 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", st.hour, st.min, st.sec);
crdPos.X = cxCenter - 4;
crdPos.Y = cyCenter;
SetConsoleCursorPosition(hStdout, crdPos);
printf(buf);
}
#ifdef USE_TIMERQUEUE
// if we use the timer queue function.
// Its procdure is in this.
void 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);
}
}
#else
DWORD 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 (msg.message == 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 program.
BOOL 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);
csbiInfo.srWindow.Right = 40;
// get the center point.
g_cxCenter = csbiInfo.srWindow.Right / 2;
g_cyCenter = csbiInfo.srWindow.Bottom / 2;
// Set the window.
SetConsoleWindowInfo(g_hStdout, TRUE, &csbiInfo.srWindow);
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;
crdPos.X = cxCenter + GAPS_LEFT_COLON;
crdPos.Y = cyCenter;
SetConsoleCursorPosition(hStdout, crdPos);
printf (":");
crdPos.X = cxCenter + GAPS_RIGHT_COLON;
SetConsoleCursorPosition(hStdout, crdPos);
printf (":");
crdPos.X = cxCenter + GAPS_LEFT_UNDERLINE_START;
SetConsoleCursorPosition(hStdout, crdPos);
scanf ("%d", &time.hour);
crdPos.X = cxCenter + GAPS_MIDDLE_UNDERLINE_START;
SetConsoleCursorPosition(hStdout, crdPos);
scanf ("%d", &time.min);
crdPos.X = cxCenter + GAPS_RIGHT_UNDERLINE_START;
SetConsoleCursorPosition(hStdout, crdPos);
scanf ("%d", &time.sec);
if (time.hour < 0 || time.hour > HOUR_CIRCLE ||
time.min < 0 || time.min > MINUTE_CIRCLE ||
time.sec < 0 || time.sec > 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的。
有几个问题:
1.textmode函数在turboc中没有办法使用,不知道是什么问题,而borland c就可以。
2.无论怎么设置,自己的ctrlbreak函数在上述两个环境中都不能被调用,非常遗憾。所以不能够优雅的退出。只能按两次ctrlbreak。
下面是程序。
------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#define ABORT 0
int 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 = ti.winright / 2;
center_y = ti.winbottom / 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;
}
温馨提示:内容为网友见解,仅供参考
求一个关于用C语言编写的电子时钟的程序,内容要有闹钟,可以调整时间...
define uchar unsigned char \/\/#define HZ 12 sbit key0=P0^0; \/\/ 分钟调整 sbit key1=P0^1; \/\/ 小时调整 sbit P2_0=P2^7; \/\/秒 指示灯 sbit MN_RXD=P3^6;sbit MN_TXD=P3^7;uchar data CLOCK[4]={0,0,0,12};\/\/存放时钟时间(百分秒,秒,分,和时位)\/\/数码管...
c语言怎么样编写一个时钟程序
pt[0].y=900;RotatePoint(pt,1,iAngle);pt[2].x=pt[2].y=iAngle%5?33:100;pt[0].x-=pt[2].x\/2;pt[0].y-=pt[2].y\/2;pt[1].x=pt[0].x+pt[2].x;pt[1].y=pt[0].y+pt[2].y;SelectObject(hdc,GetStockObject(BLACK_BRUSH));Ellipse(hdc,pt[0].x,pt[0].y,...
c语言 数字时钟程序 要求显示格式为:HH:MM:SS
include include <stdio.h> include <stdlib.h> define BUF_SIZE 80 int main(){ time_t t;struct tm *tm;char s[BUF_SIZE];if(time(&t) == ((time_t)-1)) return 1;tm = localtime(&t);if(!tm) return 1;strftime(s, sizeof(s), ":%H:%M:%S", tm);printf("%s\\n",...
用c语言模拟一个数字时钟,要求延时一秒运行
&graphmode,"C:\\\\TC2"); \/\/初始化VGA屏幕模式setbkcolor(BLACK); \/\/使用黑色的背景色while(!kbhit(0)) \/\/若有键盘输入,则跳出,即是结束程序{ setcolor(GREEN); \/\/把画笔设为绿色circle(mid_x,mid_y,180); \/\/钟的外圆circle(mid_x,mid_y,150); \/\/钟的内圆circle(mid_x,mid_y,...
用C语言做数字时钟每走一秒响一次,求大神告诉源代码
数字时钟的实现很简单,运用time.h相关函数即可 include<stdio.h>#include<stdlib.h>#includetime_t oldt=-1;struct tm *p;bool Printdate(){time_t t=time(NULL);if(t!=oldt){oldt=t;p=localtime(&t);system("cls");printf("%d\/%d\/%d 周",1900+p->tm_year,1+p->tm_mon,p->t...
c语言 时钟模拟
while(!kbhit()) \/\/若有键盘输入则跳出(结束程序){ draw(); \/\/绘制钟 settextstyle(3,0,5);setcolor(9);outtextxy(60,170,"my clock");gotoxy(35,17);\/\/打印出数字形式的时间(hh:mm:ss)if(h<10) printf("0");printf("%d:",h);if(m<10) printf("0");printf("%d:",m);...
单片机C语言该怎么编写时钟程序?
这个是简单的数码管时钟显示如果有需要,我写过比较完善的1602显示时钟.显示控制年月日等等.#include<reg51.h> sbit Begin=P2^0;sbit Hour=P2^1;sbit Mus=P2^2;sbit End=P2^3;unsigned char code Tab[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x...
用C语言编数码管时钟程序
\/*实验名称:定时中断0 功能:利用定时器,产生秒计数器,使数码管显示时间和年月日,还有跑表。05-02-01 \/ include <reg51.h> \/\/LCD的口线 sbit E=P3^5;sbit RW=P3^6;sbit RS=P3^7;\/\/8字LED的连接方法 \/\/P0.7,P0.6,P0.5,P0.4,P0.3,P0.2,P0.1,P0.0 \/\/G, F ...
单片机控制多位数码管的电子时钟程序
软件编程: keil工程C语言代码:\/*** 项目名称:数码管电子时钟 实现功能:数码管显示时间、日期,时间、日 期可调,可设置闹钟,闹铃响一分钟。 ***\/ #include reg52.h #define uint unsigned int #define uchar unsigned char uint numwe,tt,t,numdu,set,aclock,rili; unsigned long int time...
用C语言编写程序使89C52单片机实现数字时钟功能,显示时分秒的数码管,p1...
char code wema[]={0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7}; \/\/片选,1-8个数码管 char j;char h_num,m_num,s_num; \/\/分别定义小时、分钟、秒 char h_shi,h_ge,m_shi,m_ge,s_shi,s_ge;sbit fm=P3^4;void delay(char x){ char a,b;for(a=x;a>0;a--)f...