| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2864 人关注过本帖
标题:写了个唐诗组合任务小程序,有兴趣大家研究一下。
只看楼主 加入收藏
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
谢谢各位老大的建议,水越淌越深咯。

梅尚程荀
马谭杨奚







                                                       
2012-02-04 21:32
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:5 
用C在控制台下是可以做的,不用多线程。

授人以渔,不授人以鱼。
2012-02-04 22:27
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 12楼 TonyDeng
那么就解释一下怎么做吧。只要不是TSR程序。

如果你愿意写一个控制台的代码,那我就写一个视窗的。

重剑无锋,大巧不工
2012-02-04 23:26
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
要顯示倒數,必須用控制臺API,喜歡就自己補充。

關於time()函數:

The time function returns the number of seconds elapsed since midnight (00:00:00), January 1, 1970, Coordinated Universal Time (UTC), according to the system clock. The return value is stored in the location given by timer. This parameter may be NULL, in which case the return value is not stored.

time is a wrapper for _time64 and time_t is, by default, equivalent to __time64_t. If you need to force the compiler to interpret time_t as the old 32-bit time_t, you can define _USE_32BIT_TIME_T. This is not recommended because your application may fail after January 18, 2038; the use of this macro is not allowed on 64-bit platforms.

程序代码:
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <conio.h>

#define K_ENTER        0x0D 

// 用法:InputString 是接收的字符串數組用於返回,Seconds 是限時秒數,輸入時按Enter鍵結束
bool GetString(char InputString[], unsigned long int Seconds);

void main(void)
{
    char Buffer[1024];

    GetString(Buffer, 5UL);                              // 測試限5秒
    printf_s("\nInput string is: %s\n", Buffer);         // 輸出接收的字符串,如果超時為空串

    _getch();
}

bool GetString(char InputString[], unsigned long int Seconds)
{
    time_t Start;                  // 開始時間
    time_t End;                    // 結束時間
    int Character = '\0';          // 輸入的字符
    unsigned int Counter = 0;      // 字符計數器
    bool Success = true;

    time(&Start);
    do
    {
        time(&End);
        if (End - Start >= Seconds)
        {
            Success = false;
            Counter = 0;
            break;
        }
        if (_kbhit())
        {
            Character = _getch();
            if (isprint(Character) && (Character != K_ENTER))
            {
                InputString[Counter++] = Character;             // 本例匆忙,沒寫字符計數超界檢查代碼,安全代碼必須寫上
                _putch(Character);
            }
        }
    } while(Character != K_ENTER);
    InputString[Counter] = '\0';

    return Success;
}


[ 本帖最后由 TonyDeng 于 2012-2-5 01:46 编辑 ]

授人以渔,不授人以鱼。
2012-02-05 01:28
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
加上字符計數檢測的代碼
編程環境:VS2010 SP1,.NET Framework4
移植性事項:1.帶_s後綴為新型安全函數,不兼容的編譯器,請替換為舊版函數名稱;
            2._getch()、_putch()、_kbhit()是MSC庫函數,用TC、BC系列的,沒有下劃線,即getch()、putch()、kbhit(),在conio.h頭中

btw: 這個函數使用的死循環輪詢模式是傳統DOS系統下面向對象引發事件的標準做法,也是Windows下C編程中WndPro()過程的機制,根本上Windows就是這樣寫出來的。hellovfp說的那個tt遊戲,也用這種原理寫即可,機器夠快,穿插做其他事感覺很輕微。當然,若有系統中斷會帶來某種方便,不過並非全依賴中斷不可。kbhit()其實是系統鍵盤中斷函數,但這裡的用法卻不算是使用了中斷。如果要顯示跳錶式的倒計時畫面,只要有光標自由跳動的功能即可,跳開去顯示時間然後返回來,這樣的功能是控制臺流模式無法做到的,必須用conio.h中的寫屏技術,TC/BC中有現成的gotoxy()函數,VC中要調用API的SetCursorPosition()函數(要麼用CLR的Console命名空間),只是這樣與操作系統的結合緊密許多,也正是conio.h頭不入標準庫的原因。我曾經在壇上貼過的仿LED時鐘就是這樣做的,在控制臺下顯示類似Windows的狀態欄,很早就不存在問題了,TC/BC IDE介面就是這種東西,在以前不會寫這樣的程序簡直無法混IT,後來的人一開始就接觸Windows不知道舊式程序是怎麼寫的,才覺得控制臺程序只能黑漆漆罷了,TC/BC五顏六色的介面你以為是Windows的窗口控件?

   
程序代码:
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <conio.h>

#define K_ENTER        0x0D

bool GetString(char InputString[], size_t Length, unsigned long int Seconds);

void main(void)
{
    char Buffer[6];

    printf_s("Please type a string, max %d characters, Press Enter to confirm: ", sizeof(Buffer) - 1);
    GetString(Buffer, sizeof(Buffer) - 1, 5UL);
    printf_s("\nYour input is: %s\n", Buffer);

    _getch();
}

bool GetString(char InputString[], size_t Length, unsigned long int Seconds)
{
    time_t Start;                  // 開始時間
    time_t End;                    // 結束時間
    int Character = '\0';          // 輸入的字符
    size_t Counter = 0;            // 字符計數器
    bool Success = true;

    if (Length < 1)                // 只容納一個字符的字符串直接返回空串,並報告輸入失敗
    {
        InputString[0] = '\0';
        return false;
    }

    time(&Start);
    do
    {
        time(&End);
        if (End - Start >= Seconds)
        {
            Success = false;
            Counter = 0;           // 如果需要超時保留已輸入的字符串,則此處不要歸零
            break;
        }
        if (_kbhit())
        {
            Character = _getch();
            if (Character == 0xE0)
            {
                // 沒收控制鍵,諸如BackSpace、Delete、TAB、光標鍵等均不接受
                _getch();
                continue;
            }
            if (isprint(Character) && (Character != K_ENTER))
            {
                // 本代碼全程使用ANSI版本的函數,isprint()是排斥中文字符的,因此若要輸入中文,不使用isprint()即可,但
                // 要檢測中文字符,對應Counter += 2(與系統的編碼體系有關),否則有字符串溢出危險。改用寬字符版本函數
                // 可有效避免此種麻煩。
                InputString[Counter++] = Character;
                _putch(Character);
            }
        }
    } while((Character != K_ENTER) && (Counter < Length));
    InputString[Counter] = '\0';

    return Success;
}


[ 本帖最后由 TonyDeng 于 2012-2-5 04:13 编辑 ]

授人以渔,不授人以鱼。
2012-02-05 02:15
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用TonyDeng在2012-2-5 02:15:54的发言:

編程環境:VS2010 SP1,.NET Framework4
移植性事項:1.帶_s後綴為新型安全函數,不兼容的編譯器,請替換為舊版函數名稱;
            2._getch()、_putch()、_kbhit()是MSC庫函數,用TC、BC系列的,沒有下劃線,即getch()、putch()、kbhit(),在conio.h頭中

btw: 這個函數使用的死循環輪詢模式是傳統DOS系統下面向對象引發事件的標準做法,也是Windows下C編程中WndPro()過程的機制,根本上Windows就是這樣寫出來的。hellovfp說的那個tt遊戲,也用這種原理寫即可,機器夠快,穿插做其他事感覺很輕微。當然,若有系統中斷會帶來某種方便,不過並非全依賴中斷不可。kbhit()其實是系統鍵盤中斷函數,但這裡的用法卻不算是使用了中斷。如果要顯示跳錶式的倒計時畫面,只要有光標自由跳動的功能即可,跳開去顯示時間然後返回來,這樣的功能是控制臺流模式無法做到的,必須用conio.h中的寫屏技術,TC/BC中有現成的gotoxy()函數,VC中要調用API的SetCursorPosition()函數(要麼用CLR的Console命名空間),只是這樣與操作系統的結合緊密許多,也正是conio.h頭不入標準庫的原因。我曾經在壇上貼過的仿LED時鐘就是這樣做的,在控制臺下顯示類似Windows的狀態欄,很早就不存在問題了,TC/BC IDE介面就是這種東西,在以前不會寫這樣的程序簡直無法混IT,後來的人一開始就接觸Windows不知道舊式程序是怎麼寫的,才覺得控制臺程序只能黑漆漆罷了,TC/BC五顏六色的介面你以為是Windows的窗口控件?

     
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <conio.h>

 
#define K_ENTER        0x0D
 
bool GetString(char InputString[], size_t Length, unsigned long int Seconds);
 
void main(void)
{
    char Buffer[6];
 
    printf_s("Please type a string, max %d characters, Press Enter to confirm: ", sizeof(Buffer) - 1);
    GetString(Buffer, sizeof(Buffer) - 1, 5UL);
    printf_s("\nYour input is: %s\n", Buffer);
 
    _getch();
}
 
bool GetString(char InputString[], size_t Length, unsigned long int Seconds)
{
    time_t Start;                  // 開始時間
    time_t End;                    // 結束時間
    int Character = '\0';          // 輸入的字符
    size_t Counter = 0;            // 字符計數器
    bool Success = true;
 
    if (Length < 1)                // 只容納一個字符的字符串直接返回空串,並報告輸入失敗
    {
        InputString[0] = '\0';
        return false;
    }
 
    time(&Start);
    do
    {
        time(&End);
        if (End - Start >= Seconds)
        {
            Success = false;
            Counter = 0;           // 如果需要超時保留已輸入的字符串,則此處不要歸零
            break;
        }
        if (_kbhit())
        {
            Character = _getch();
            if (Character == 0xE0)
            {
                // 沒收控制鍵,諸如BackSpace、Delete、TAB、光標鍵等均不接受
                _getch();
                continue;
            }
            if (isprint(Character) && (Character != K_ENTER))
            {
                // 本代碼全程使用ANSI版本的函數,isprint()是排斥中文字符的,因此若要輸入中文,不使用isprint()即可,但
                // 要檢測中文字符,對應Counter += 2(與系統的編碼體系有關),否則有字符串溢出危險。改用寬字符版本函數
                // 可有效避免此種麻煩。
                InputString[Counter++] = Character;
                _putch(Character);
            }
        }
    } while((Character != K_ENTER) && (Counter < Length));
    InputString[Counter] = '\0';
 
    return Success;
}
谢谢T版的代码,研究了下有几个问题请教:
1.size_t的使用,度娘说size_t是一个无符号整数memsize基地型的C / C + +语言的标准库中定义的,头文件是
stddef.h。那么ctype.h和他是否有相似的作用?size_t不一定和int同长度,而是视机器而定?
2.  为什么是sizeof(Buffer) - 1而不用 sizeof(Buffer),貌似 这样Buffer【6】只能输出最大长度是5个字符。
3. if (Character == 0xE0)
            {
                // 沒收控制鍵,諸如BackSpace、Delete、TAB、光標鍵等均不接受
                _getch();
                continue;
            }
   是不是如果输入BackSpace、Delete、TAB、光標鍵都将返回0xE0?将0xE0改成0可不可以?我测试了下有个有趣的现象,即在长度小于最大长度时结尾输入上面中的一个系统将不回显字符串。
图片附件: 游客没有浏览图片的权限,请 登录注册

梅尚程荀
马谭杨奚







                                                       
2012-02-05 09:22
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 15楼 TonyDeng
我猜你也会用kbhit。感觉你很怀念DOS时代,对后来的人不会用这个系统很不屑,对我的偏见估计也来源于此。
而我对你的偏见的主要原因在于只见你批评别人说些形而上的大话,却不见实际解决问题的办法,代码更难得一见。
虽然不知道你的实际年龄,应该比我大。说来也很有意思,你我吵完架后都在尽量保持克制(偶尔的影射还是能看出来的),不过我们很少在回帖中相遇,这好像倒不是有意为之。我喜欢回复算法类提问贴,你对此很不屑;而你愿意回答的语法基础类问贴,我也一样的不屑(我很怀疑你现在是不是还在做程序员,说话口气很像做HR的)。

这一贴的初衷不是为了吵架。当然也没指望能化解矛盾,毕竟你我立场截然不同。抛开个人的对立因素,这两个立场正是软件的内外两个方面,本是相互支撑的,何来对立?

回到正题还是谈谈代码。
我倒不是故意刁难你,但你的代码只能算时间控制这一环节的演示。单独一个环节并没什么难度,难点在于和其它功能环节的整合协作。
如果你愿意,我想看的是你如何完成这整个程序,如何划分功能模块,模块之间的协作调用关系。这不正是你一直说的“实用软件”的核心——软件工程么?
你这部分控制台的功能演示,我在视窗下的作法如下:
以文本框控件接受键盘输入,在它的change事件里处理输入数据。
使用定时器Timer控制时间,在tick事件中更新时间的显示、更改文本框的enable属性以开断用户输入,等等。
这么点东西,我就懒得写代码了。不过如果写完整的程序,我不会用文本框,因为没必要接收键盘输入,鼠标的操作足以完成程序的目的。

最后,更正一个留给你的错误印象。虽然只是玩,我在DOS系统下写过五年(初中及高中时代)的程序。TC下的图形编程就不说了,当时很痴迷分形图案的。为模拟多任务,也写过TSR程序。所以,我对DOS的了解程度并没有你想像的那么少。还有一点,DOS和控制台是两码事,一个是操作系统,一个是操作界面,不是一个层面的事情。它俩的联系只在于都是命令行界面而已。

重剑无锋,大巧不工
2012-02-05 10:36
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 16楼 有容就大
1.size_t是C99新加的,隨數據類型不同而不同,專用於表示個數、計數器之類數據,這些數據必定是無符號數,未必是int,不要假定它是int還是long。ctype.h只用於字符歸類,與數據類型無關。
2.C語言用0作字符串結束符,數組s[n]只能容納n-1個字符。
3.輸入控制符是即時被廢掉,不進入字符串,可以繼續按鍵的,不會返回,只是等同於你沒有輸入一樣。按下控制鍵,鍵盤緩衝區中有兩個字符,以0xE0開頭為標誌,而普通字符只有一個字符。


[ 本帖最后由 TonyDeng 于 2012-2-5 10:55 编辑 ]

授人以渔,不授人以鱼。
2012-02-05 10:43
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
在Windows控件中有timer時間中斷器,不需要在change事件中處理。Windows環境下,仍用C寫程序是多餘的。

授人以渔,不授人以鱼。
2012-02-05 10:50
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
回复 18楼 TonyDeng
3.輸入控制符是即使被廢掉,不進入字符串,可以繼續按鍵的,不會返回,只是等同於你沒有輸入一樣。
哦,我的问题是这样的,即在一串已经输入的字符串后输入一个控制符,那么整个前面的字符都将不回显。

梅尚程荀
马谭杨奚







                                                       
2012-02-05 10:54
快速回复:写了个唐诗组合任务小程序,有兴趣大家研究一下。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016768 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved