| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2879 人关注过本帖
标题:自编的从键盘读取数据的函数
取消只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
结帖率:100%
收藏
 问题点数:0 回复次数:7 
自编的从键盘读取数据的函数
程序代码:
#include <conio.h>
#include <string.h>
#include "get.h"

void Print(wchar_t cBuffer[]);
void Print(int iVar);

// 主程序入口
void main(void)
{
    wchar_t cText[1024];
    int iVar;
    GET Get;

    Print(L"请输入50个字符以内的字符串: ");
    if (Get.Read(cText, 50))
    {
        Print(L"\n您输入的字符串是: ");
        Print(cText);
    }
    else
    {
        Print(L"\n== 输入中断 ==");
    }

    Print(L"\n\n请输入10个字符以内的整数: ");
    iVar = Get.Read(10);
    Print(L"\n您输入的整数是: ");
    Print(iVar);

    Print(L"\n\n按Esc键结束程序……");
    while (_getwch() != K_ESC)
    {
        ;
    }
}

// 输出字符串
void Print(wchar_t cBuffer[])
{
    while (*cBuffer)
    {
        _putwch(*cBuffer);
        cBuffer++;
    }
}

// 输出整数
void Print(int iVar)
{
    wchar_t Buffer[256];
    unsigned int nCount;
    bool IsNegative;
    size_t Length = 0;

    if (iVar != 0)
    {
        IsNegative = (iVar < 0);
        if (IsNegative)
        {
            iVar = -iVar;
        }
        Length = 0;
        nCount = 0;
        while (iVar > 0)
        {
            nCount++;
            if (nCount > 3)
            {
                Buffer[Length++] = ',';
                nCount = 1;
            }
            Buffer[Length] = '0' + iVar % 10;
            iVar /= 10;
            Length++;
        }
        if (IsNegative)
        {
            Buffer[Length++] = '-';
        }
    }
    Buffer[Length] = '\0';
    _wcsrev(Buffer);
    Print(Buffer);
}
搜索更多相关主题的帖子: 键盘 
2011-08-10 13:26
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
需要包含的get.h头文件
程序代码:
// 键码常数
#ifndef _KEYCODE
    #define _KEYCODE
    const wctype_t K_NUL       = 0x0000;        // 空字符
    const wctype_t K_SOH       = 0x0001;        // 标题开始
    const wctype_t K_STX       = 0x0002;        // 正文开始
    const wctype_t K_ETX       = 0x0003;        // 正文结束
    const wctype_t K_EOT       = 0x0004;        // 传输结束
    const wctype_t K_ENQ       = 0x0005;        // 请求
    const wctype_t K_ACK       = 0x0006;        // 收到通知
    const wctype_t K_BEL       = 0x0007;        // 响铃
    const wctype_t K_BACKSPACE = 0x0008;        // 退格
    const wctype_t K_TAB       = 0x0009;        // 水平制表符
    const wctype_t K_LF        = 0x000A;        // 换行
    const wctype_t K_VT        = 0x000B;        // 垂直制表符
    const wctype_t K_FF        = 0x000C;        // 换页符
    const wctype_t K_ENTER     = 0x000D;        // 回车
    const wctype_t K_SO        = 0x000E;        // 不用切换
    const wctype_t K_SI        = 0x000F;        // 启用切换
    const wctype_t K_DLE       = 0x0010;        // 数据链路转义
    const wctype_t K_DC1       = 0x0011;        // 设备控制1
    const wctype_t K_DC2       = 0x0012;        // 设备控制2
    const wctype_t K_DC3       = 0x0013;        // 设备控制3
    const wctype_t K_DC4       = 0x0014;        // 设备控制4
    const wctype_t K_NAK       = 0x0015;        // 拒绝接收
    const wctype_t K_SYN       = 0x0016;        // 同步空闲
    const wctype_t K_ETB       = 0x0017;        // 传输块结束
    const wctype_t K_CAN       = 0x0018;        // 取消/作废
    const wctype_t K_EM        = 0x0019;        // 介质中断
    const wctype_t K_SUB       = 0x001A;        // 替补
    const wctype_t K_ESC       = 0x001B;        // 溢出
    const wctype_t K_FS        = 0x001C;        // 文件分割符
    const wctype_t K_GS        = 0x001D;        // 分组符
    const wctype_t K_RS        = 0x001E;        // 记录分离符
    const wctype_t K_US        = 0x001F;        // 单元分隔符
    const wctype_t K_SPACE     = 0x0020;
    const wctype_t K_CDEL      = 0x007F;        // ASCII DEL
    const wctype_t K_UP        = 0xE048;
    const wctype_t K_DOWN      = 0xE050;
    const wctype_t K_LEFT      = 0xE04B;
    const wctype_t K_RIGHT     = 0xE04D;
    const wctype_t K_HOME      = 0xE047;
    const wctype_t K_END       = 0xE04F;
    const wctype_t K_PGUP      = 0xE049;
    const wctype_t K_PGDN      = 0xE051;
    const wctype_t K_INS       = 0xE052;
    const wctype_t K_DEL       = 0xE053;
#endif

class GET
{
    private:
        bool IsAscii(const wchar_t Character);                // 检测是否ASCII字符
        bool IsHz(const wchar_t Character);                    // 检测是否汉字
        wctype_t Read_Key(void);                            // 从键盘读入一键

    public:
        bool Read(wchar_t* String, const size_t nSize);        // 从键盘读入字符串
        int Read(const size_t nSize);                        // 从键盘读入整数
};


[ 本帖最后由 TonyDeng 于 2011-8-10 13:33 编辑 ]

授人以渔,不授人以鱼。
2011-08-10 13:28
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
需要联编的get.cpp源代码
程序代码:
#include <conio.h>
#include "get.h"

// 检测是否ASCII字符
bool inline GET::IsAscii(const wchar_t Character)
{
    return ((Character >= 0x0020) && (Character <= 0x007E)) || ((Character >= 0xF900) && (Character <= 0xFA2D));
}

// 检测是否汉字
bool inline GET::IsHz(const wchar_t Character)
{
    return (Character >= 0x4E00) && (Character <= 0x9FA5);
}

// 从键盘读入一个按键, 返回其键码
wctype_t inline GET::Read_Key(void)
{
    wint_t KeyCode = _getwch();
    if (KeyCode == 0xE0)
    {
        KeyCode = (KeyCode << 8) + _getwch();
    }
    return KeyCode;
}

// 读入字符串
bool GET::Read(wchar_t* String, const size_t nSize)
{
    size_t Length = 0;
    wctype_t KeyCode;
    String[Length] = '\0';

    do
    {
        KeyCode = Read_Key();
        switch (KeyCode)
        {
            case K_ESC:
                String[0] = '\0';
                return false;
            case K_ENTER:
                break;
            case K_BACKSPACE:
                if (Length > 0)
                {
                    Length--;
                    if (IsAscii(String[Length]))
                    {
                        String[Length] = K_SPACE;
                        _putwch(K_BACKSPACE);
                        _putwch(String[Length]);
                        _putwch(K_BACKSPACE);
                    }
                    if (IsHz(String[Length]))
                    {
                        String[Length] = K_SPACE;
                        _putwch(K_BACKSPACE);
                        _putwch(K_BACKSPACE);
                        _putwch(String[Length]);
                        _putwch(K_BACKSPACE);
                    }
                }
                else _putwch(K_BEL);
                break;
            default:
                String[Length] = KeyCode;
                _putwch(String[Length]);
                Length++;
                String[Length] = '\0';
        }
    } while ((Length < nSize) && (KeyCode != K_ENTER));
    return true;
}

// 从键盘读入整数
int GET::Read(const size_t nSize)
{
    wchar_t Buffer[1024];
    size_t Length = 0;
    wctype_t KeyCode;
    int iVar;

    Buffer[Length] = '\0';
    do
    {
        KeyCode = Read_Key();
        switch (KeyCode)
        {
            case K_ESC:
            case K_ENTER:
                break;
            case K_BACKSPACE:
                if (Length > 0)
                {
                    Length--;
                    Buffer[Length] = K_SPACE;
                    _putwch(K_BACKSPACE);
                    _putwch(Buffer[Length]);
                    _putwch(K_BACKSPACE);
                }
                else _putwch(K_BEL);
                break;
            case '-':
                if (Length == 0)
                {
                    Buffer[Length] = KeyCode;
                    _putwch(Buffer[Length]);
                    Length++;
                    Buffer[Length] = '\0';
                }
                else _putwch(K_BEL);
                break;
            default:
                if ((KeyCode >= '0') && (KeyCode <= '9'))
                {
                    Buffer[Length] = KeyCode;
                    _putwch(Buffer[Length]);
                    Length++;
                    Buffer[Length] = '\0';
                }
                else _putwch(K_BEL);
        }
    } while ((Length < nSize) && (KeyCode != K_ENTER));

    // 将字符串转换为整数
    register size_t nIndex = 0;
    if (Buffer[0] == '-')
    {
        nIndex = 1;
    }
    iVar = 0;
    while (Buffer[nIndex])
    {
        iVar = iVar * 10 + (Buffer[nIndex] - '0');
        nIndex++;
    }
    if (Buffer[0] == '-')
    {
        iVar = -iVar;
    } 

    return iVar;
}


[ 本帖最后由 TonyDeng 于 2011-8-10 13:36 编辑 ]

授人以渔,不授人以鱼。
2011-08-10 13:31
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 4楼 zerokingf1
连编是多个源代码文件所需要的。没有人会将一个程序的所有代码都写在一个文件中,必然会把不同功能的模块分开写,连编就是把这些分开的代码组装在一起,构成最终的可执行文件(编译的时候,同时把LIB运行库也连编进来)。

我这个程序,正如你看到,它使用了get.cpp中的函数,所以这个get.cpp是程序的一部分,是一体的。分开文件编写的好处,是把相对独立的函数、模块划分开来,可被别的程序使用。在这里,get.cpp中的类,并不是这个程序专用的,当我们写别的程序时,也要使用同样的函数,此时这些函数就无需重写,把它连编到新的程序中就可以了。所以,只要将这些模块文件调试好,就是所谓的可重用性代码。一个程序员最宝贵的东西,是拥有一整套自己的函数库(正如我们现在使用scanf()、printf()等标准库函数是别人编好的模块库一样),不是你每次都能飞快地写以前写过的、大同小异的代码,那样写程序是能力低下的表现,没有任何高级程序员会同意这种做法。我很奇怪,某些人以为我这样写程序是把程序弄复杂了,那其实是他完全没入门的眼光,就如未入段的围棋手看入段棋手下棋一样,弄不明白人家为什么会这样下棋。

授人以渔,不授人以鱼。
2011-08-10 16:20
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
多年前用的C/C++编程,后来很少用了,没什么很强烈的需要使用C/C++,现在有一点需求,就重新捡回来练练手。写这个主要是摸索Unicode编码字符串的处理,因为现在及未来的系统都是走向Unicode编码的,你们现在普遍使用的ANSI编码五年内将会被淘汰,练得越熟,后果越严重,信不信由你,呵呵。

有人说我这里使用wchar_t数据类型是Windows专用的,笑话,此人不知道wchar_t不过是被typedef了的unsigned int而已,可见很多人眼中的C和C++区别是多么狭窄。狭窄也罢了,更糟糕的是门户之分,C和C++要井水不犯河水才中他们的意,华山派里的剑宗和气宗之争,也不过如此。

授人以渔,不授人以鱼。
2011-08-10 16:43
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
其实,这个程序也没使用什么C++的独特功能,基本上是基于C的,熟悉纯粹C的人很容易就能改过来(把class中的函数全部写到外面就是了)。完整C++版本就有更多的改动了,比如应建立键盘缓冲区放在类中,供类函数公用,而不是像现在这样靠参数传来传去,现在还有一部分重复的代码,看着很不舒服的,必须要改掉。

这里唯一用了C++功能的地方,是函数重载,注意有两个Read()函数两个Print()函数,不同的函数可以用同一个名字,这才是C++的东西,C无法做到,但C程序员其实都极其希望有这种东西,所以才发展出C++,就是为了圆C程序员之梦的。

[ 本帖最后由 TonyDeng 于 2011-8-10 17:12 编辑 ]

授人以渔,不授人以鱼。
2011-08-10 17:07
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
是的,是VS2010。

授人以渔,不授人以鱼。
2011-08-11 11:51
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
可以的,带w的函数,是一次读、写两个字节,写一个函数就可以实现它们。经典的是_putch()和_getch(),对应ANSI编码,一次一个字节,在Unicode编码版本,一次两个字节,本身是调用两次前者得到的。留意wctype_t的数据类型,那其实是unsigned int,在32位系统中,是两个字节,所以对应的数据是4位十六进制整数。所有的字符用Unicode编码,意思是都是双字节字符。

如果你把代码的函数改成ANSI单字节的版本,也是可以的(其实这个版本本来就是从那个版本转化而来),不过那样处理汉字时比较复杂,在确认从来不处理汉字的时候,可以沿用旧式的方法。原理是一样的。

授人以渔,不授人以鱼。
2011-08-11 12:02
快速回复:自编的从键盘读取数据的函数
数据加载中...
 
   



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

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