鱼C论坛

 找回密码
 立即注册
查看: 2117|回复: 6

[已解决]用getch()来替换scanf()

[复制链接]
发表于 2019-12-3 22:20:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
编写自定义整数输入函数

函数原型为:int inputInt(int min, int max);

说明:入参min和max分别表示该函数输出的最小和最大值。

功能基本要求:

在windows操作系统下,使用codeblocks做为开发工具。函数实现过程中,只能使用getch()做为键盘的输入,不得使用scanf、gets之类的系统函数。以回车键结束输入,对于不符合要求的输入提供合理的解决方法,支持退格键,支持16进制输入(以0x或0X开始,16进制支持a-f和A-F),对于10进制方式的输入,不能以0开始输入。

调用示例:

    int x;

    x = inputInt(1, 500);

输入示例:

    输入“123<回车>”,则函数返回整数123

    输入“0x123<回车>”,则函数返回整数291
最佳答案
2019-12-4 01:30:40
本帖最后由 jackz007 于 2019-12-4 01:46 编辑
#include <stdio.h>
#include <conio.h>

inputInt(void)
{
        char c , s[82]                                                                          ;
        int a , d , e , k , m                                                                   ;
        bool f                                                                                  ;

        for(m = 0 ; (c = getch()) != 0x0d && m < 81 ;) {
                if(c == 8) {
                        if (m) {
                                printf("\b \b")                                                 ;
                                s[m - 1] = 0x00                                                 ;
                                m --                                                            ;
                        }
                } else {
                        s[m ++] = c                                                             ;
                        printf("%c" , c)                                                        ;
                }
        }
        printf("\n")                                                                            ;
        for(; (s[m - 1] == 0x09 || s[m - 1] == 0x20) && m > 0 ; s[m -- - 1] = 0)                ;
        for(e = 0 ; (s[e] == 0x09 || s[e] == 0x20) && e < m ; e ++)                             ;
        for(k = e ; k < m + 1 ; k ++) s[k - e] = s[k]                                           ;
        m -= e                                                                                  ;
        e = 0                                                                                   ;
        if(m > 0) {
                if(m > 1 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
                        if(m > 2) {
                                for(f = true , k = 2 ; k < m && f ; k ++) {
                                        if(s[k] >= '0' && s[k] <= '9') d = s[k] - '0'           ;
                                        else if(s[k] >= 'a' && s[k] <= 'f') d = 10 + s[k] - 'a' ;
                                        else if(s[k] >= 'A' && s[k] <= 'F') d = 10 + s[k] - 'A' ;
                                        else f = false                                          ;
                                        if(f) e = e * 16 + d                                    ;
                                }
                                if(! f) e = 0                                                   ;
                        }
                } else {
                        a = 0                                                                   ;
                        if(s[a] == '-') a ++                                                    ;
                        if(m > a) {
                                if(s[a] != '0') {
                                        for(f = true , k = a ; k < m && f ; k ++) {
                                                if(s[k] >= '0' && s[k] <= '9') d = s[k] - '0'   ;
                                                else f = false                                  ;
                                                if(f) e = e * 10 + d                            ;
                                        }
                                        if(! f) e = 0                                           ;
                                        else if(a) e = -e                                       ;
                                }
                        }                        
                }
        }
        return e                                                                                ;
}

main(void)
{
        int d              ;
        d = inputInt()     ;
        printf("%d\n" , d) ;
}
        编译运行实况:
C:\Bin>g++ -static -o getint getint.c

C:\Bin>getint
                                0x123
291

C:\Bin>getint
                        123
123

C:\Bin>

        inputInt() 可以自动去掉输入数字过程中输入的前导以及尾随的空格及 TAB 字符。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-12-4 01:30:40 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2019-12-4 01:46 编辑
#include <stdio.h>
#include <conio.h>

inputInt(void)
{
        char c , s[82]                                                                          ;
        int a , d , e , k , m                                                                   ;
        bool f                                                                                  ;

        for(m = 0 ; (c = getch()) != 0x0d && m < 81 ;) {
                if(c == 8) {
                        if (m) {
                                printf("\b \b")                                                 ;
                                s[m - 1] = 0x00                                                 ;
                                m --                                                            ;
                        }
                } else {
                        s[m ++] = c                                                             ;
                        printf("%c" , c)                                                        ;
                }
        }
        printf("\n")                                                                            ;
        for(; (s[m - 1] == 0x09 || s[m - 1] == 0x20) && m > 0 ; s[m -- - 1] = 0)                ;
        for(e = 0 ; (s[e] == 0x09 || s[e] == 0x20) && e < m ; e ++)                             ;
        for(k = e ; k < m + 1 ; k ++) s[k - e] = s[k]                                           ;
        m -= e                                                                                  ;
        e = 0                                                                                   ;
        if(m > 0) {
                if(m > 1 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
                        if(m > 2) {
                                for(f = true , k = 2 ; k < m && f ; k ++) {
                                        if(s[k] >= '0' && s[k] <= '9') d = s[k] - '0'           ;
                                        else if(s[k] >= 'a' && s[k] <= 'f') d = 10 + s[k] - 'a' ;
                                        else if(s[k] >= 'A' && s[k] <= 'F') d = 10 + s[k] - 'A' ;
                                        else f = false                                          ;
                                        if(f) e = e * 16 + d                                    ;
                                }
                                if(! f) e = 0                                                   ;
                        }
                } else {
                        a = 0                                                                   ;
                        if(s[a] == '-') a ++                                                    ;
                        if(m > a) {
                                if(s[a] != '0') {
                                        for(f = true , k = a ; k < m && f ; k ++) {
                                                if(s[k] >= '0' && s[k] <= '9') d = s[k] - '0'   ;
                                                else f = false                                  ;
                                                if(f) e = e * 10 + d                            ;
                                        }
                                        if(! f) e = 0                                           ;
                                        else if(a) e = -e                                       ;
                                }
                        }                        
                }
        }
        return e                                                                                ;
}

main(void)
{
        int d              ;
        d = inputInt()     ;
        printf("%d\n" , d) ;
}
        编译运行实况:
C:\Bin>g++ -static -o getint getint.c

C:\Bin>getint
                                0x123
291

C:\Bin>getint
                        123
123

C:\Bin>

        inputInt() 可以自动去掉输入数字过程中输入的前导以及尾随的空格及 TAB 字符。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-12-4 12:16:56 | 显示全部楼层
        for(; (s[m - 1] == 0x09 || s[m - 1] == 0x20) && m > 0 ; s[m -- - 1] = 0)                ;
        for(e = 0 ; (s[e] == 0x09 || s[e] == 0x20) && e < m ; e ++)                             ;
        for(k = e ; k < m + 1 ; k ++) s[k - e] = s[k]                                           ;代没太看懂了,可而且段代码在codeblocks编译通过不了,但还是很感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-4 17:13:37 | 显示全部楼层
本帖最后由 bin554385863 于 2019-12-4 22:11 编辑
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <ctype.h>
int inputInt()
{
    int result = 0, ct = 0, sz = 2;
    char f = '0';
    char *str = (char *)malloc(sizeof(char) * sz);
    while ((f = getch()) != '\r') //使用用动态数组存储读取的字符
    {
        str[ct] = f;
        putch(f);//回显
        ct++;
        char *tmp = (char *)malloc(sizeof(char) * (sz + ct));
        tmp[sz + ct - 1] = '\0';
        strcpy(tmp, str);
        free(str);
        str = tmp;
    }
    printf("\n");
    char res[strlen(str) + 2];
    res[0] = '+';
    res[strlen(str)] = '\0';
    if (str[0] == '-')
    {
        strcpy(res, str);
    }
    else
    {
        strcat(res, str);
    }
    free(str);
    if (res[0] == '+') //如果是正数
    {
        if (res[1] == '0' && (res[2] == 'x' || res[2] == 'X')) //如果是16进制数
        {
            for (size_t i = 3; i < strlen(res); i++)
            {
                if (isdigit(res[i]) || ((res[i] >= 'a') && (res[i] <= 'f')) || (res[i] >= 'A' && res[i] <= 'F'))
                {
                    if (isupper(res[i]))
                    {
                        res[i] = (char)(58 + res[i] - 'A');
                    }
                    else if (islower(res[i]))
                    {
                        res[i] = (char)(58 + res[i] - 'a');
                    }
                }
                else
                {
                    perror("ERROR");
                    exit(1);
                }
                result = result * 16 + (res[i] - 48);
            }
        }
        else //如果是10进制数
        {
            for (size_t i = 1; i < strlen(res); i++)
            {
                if (!isdigit(res[i]))
                {
                    perror("ERROR");
                    exit(1);
                }
                else
                {
                    result = result * 10 + (res[i] - 48);
                }
            }
        }
    }
    else if (res[0] == '-') //如果是负数
    {
        if (res[1] == '0' && (res[2] == 'x' || res[2] == 'X')) //如果是16进制数
        {
            for (size_t i = 3; i < strlen(res); i++)
            {
                if (isdigit(res[i]) || ((res[i] >= 'a') && (res[i] <= 'f')) || (res[i] >= 'A' && res[i] <= 'F'))
                {

                    if (isupper(res[i]))
                    {
                        res[i] = (char)(58 + res[i] - 'A');
                    }
                    else if (islower(res[i]))
                    {
                        res[i] = (char)(58 + res[i] - 'a');
                    }
                }
                else
                {
                    perror("ERROR");
                    exit(1);
                }
                result = result * 16 + (res[i] - 48);
            }
            result = -result;
        }
        else //如果是10进制数
        {
            for (size_t i = 1; i < strlen(res); i++)
            {
                if (!isdigit(res[i]))
                {
                    perror("ERROR");
                    exit(1);
                }
                else
                {
                    result = result * 10 + (res[i] - 48);
                }
            }
            result = -result;
        }
    }
    return result;
}
int main(int argc, char const *argv[])
{
    int x = inputInt();
    printf("%d", x);
    return 0;
}
==================================================
E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-amcrwj1k.g4k --stdout=Microsoft-MIEngine-Out-34ojn3ac.qyj --stderr=Microsoft-MIEngine-Error-lmt4kyln.wpk --pid=Microsoft-MIEngine-Pid-n005cbfs.inj --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
123
123

E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-pmbslost.gwc --stdout=Microsoft-MIEngine-Out-xfshvka4.qiy --stderr=Microsoft-MIEngine-Error-yph4nrau.az3 --pid=Microsoft-MIEngine-Pid-rb14fg1b.pdj --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
-123
-123

E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-atgvy5or.llj --stdout=Microsoft-MIEngine-Out-bwe3hyko.wok --stderr=Microsoft-MIEngine-Error-311wjcni.l4e --pid=Microsoft-MIEngine-Pid-sr4c5jcp.ccq --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
0x123
291

E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-sin3opxt.nyb --stdout=Microsoft-MIEngine-Out-a0fbswkr.b5g --stderr=Microsoft-MIEngine-Error-30dxkm0p.h2s --pid=Microsoft-MIEngine-Pid-nm2t0sdj.2bh --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
-0x123
-291

E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-g1lrueul.yhg --stdout=Microsoft-MIEngine-Out-lnjuzxo5.muv --stderr=Microsoft-MIEngine-Error-wxti4a10.xew --pid=Microsoft-MIEngine-Pid-iswgkr3q.4lz --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
lk00
ERROR: No error


E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-teqodghs.ovy --stdout=Microsoft-MIEngine-Out-lrgunujb.g0t --stderr=Microsoft-MIEngine-Error-mneikxwz.koj --pid=Microsoft-MIEngine-Pid-i2gs0wvy.q3u --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
136l
ERROR: No error


E:\Users\admin\Documents\VScode\Code>c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-yil3vgkk.odh --stdout=Microsoft-MIEngine-Out-zsfp2ehb.0q0 --stderr=Microsoft-MIEngine-Error-00f454g2.5fu --pid=Microsoft-MIEngine-Pid-pw3cpvdv.fvf --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi
0xa
10

E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-znatdx5t.ggl --stdout=Microsoft-MIEngine-Out-ngm1id0g.njp --stderr=Microsoft-MIEngine-Error-pdufa5ld.foa --pid=Microsoft-MIEngine-Pid-grtfoskv.aoo --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
-0xF
-15

E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-ov1xvfy5.oq3 --stdout=Microsoft-MIEngine-Out-mlidmuhj.t2c --stderr=Microsoft-MIEngine-Error-mc5uhumz.xwc --pid=Microsoft-MIEngine-Pid-twdsngu2.zzq --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
-0xB&
ERROR: No error


E:\Users\admin\Documents\VScode\Code>cmd /C "c:\Users\admin\.vscode\extensions\ms-vscode.cpptools-0.26.2\debugAdapters\bin\WindowsDebugLauncher.exe --stdin=Microsoft-MIEngine-In-1va50uaw.2g4 --stdout=Microsoft-MIEngine-Out-iaraai5w.xkb --stderr=Microsoft-MIEngine-Error-244syxg4.0da --pid=Microsoft-MIEngine-Pid-rg44mr2j.dws --dbgExe=D:\MinGW\bin\gdb.exe --interpreter=mi "
0xAFN
ERROR: No error


E:\Users\admin\Documents\VScode\Code>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-4 17:31:32 | 显示全部楼层
本帖最后由 ba21 于 2019-12-4 17:32 编辑

发错对像
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-4 17:33:09 | 显示全部楼层

昨晚看了下,没完成,今 天又看了下,看楼上的代码实属高手看的代码,如 果不格式化好我是没法看下去。
所以我还是按我的思路搞了段代码,给参考下:
#include <stdio.h>
#include <conio.h>

/*
16进制字符串转10进制算法:

用变量a存放转换结果,赋初值为0

逐一取得字符串每个字符:从头一直取字符,直到遇到0为止

每取得一个字符:

-变量a自乘16

-判断字符是否数字字符,如果是数字字符则直接转换成数值

-否则,判断字符是否小写字母a~f,如果是转成10~15数值

-否则,判断字符是否大写字母a~f,如果是转成10~15数值

-将以上得到的数值加到变量a上,然后进行下一个字符的处理
*/
int h2d(char *s) 
{ 
        int a=0;
        while ( *s ) 
        {
                a *= 16;
                if ( *s>='0' && *s<='9' )
                        a += *s - '0';
                else if ( *s>='a' && *s<='f' ) 
                        a += *s- 'a' + 10;
                else if ( *s>='A' && *s<='F' ) 
                        a += *s - 'A' + 10;

                s++;
        }

  return a;
}

/*
16进制字符串转10进制算法:

用变量a存放转换结果,赋初值为0

逐一取得字符串每个字符:从头一直取字符,直到遇到0为止

每取得一个字符:

-变量a自乘10

-数字字符转换成数值
*/
int d2d(char *s) 
{ 
        int a=0;
        while ( *s ) 
        {
                a *= 10;
                a += *s - '0';
                s++;
        }

  return a;
}

int inputint()
{
        int i, x;
        char num[1024] = {'\0'};
        char ch;

/* 接受输入 */
        i=0;
        while( (ch=getch())!='\r')
        {
                // 退格
                if ( (ch == 8) && (i!=0) )
                {
                        num[--i] = '\0';
                        printf("\b \b"); // 实现退格回显
                        continue;
                }

                // 不是有效字符 continue
                if ( !( (ch>='0' && ch<='9') || (ch>='a' && ch<='f') || (ch>='A' && ch<='F') || (ch=='x' || ch=='X') ) )
                {
                        continue;
                }
                
                // 先接收第1位                
                if ( i==0 ) 
                {
                        // 第1位只能'0' - '9'
                        if ( !(ch>='0' && ch<='9') )
                                continue;

                        num[i] = ch;
                        i++;
                        putch(ch); // 回显                                
                }
                else // 其它位
                {                        
                        if ( num[0]=='0' )
                        {
                                // 16进制

                                if ( i==1 )
                                {        
                                        // 第2位只能接收x
                                        if (ch!='x' && ch!='X')
                                                continue;

                                }
                                else
                                {
                                        // 第2位后只能接收'0' - '9' 'a' - 'f'
                                        if ( !(ch>='0' && ch<='9') && !(ch>='a' && ch<='f') && !(ch>='A' && ch<='F') )
                                                continue;
                                }                

                        }
                        else 
                        {
                                // 10进制

                                // 只能接收'0' - '9'
                                if ( !(ch>='0' && ch<='9') ) 
                                        continue;                        
                        }
                        num[i] = ch;
                        i++;
                        putch(ch); // 回显        
                }

        }
        printf("\n");

/* 转换 */ 
        if ( num[0]=='0')
                // 16 转 10
                x = h2d(num);
        else                
                // 10 转 10
                x = d2d(num);

        return x;
}

int main(void)
{
        int n;

        n = inputint();
        
        printf("%d\n", n);

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-4 18:31:46 | 显示全部楼层
本帖最后由 jackz007 于 2019-12-4 18:37 编辑
Oxford 发表于 2019-12-4 12:16
for(; (s[m - 1] == 0x09 || s[m - 1] == 0x20) && m > 0 ; s[m -- - 1] = 0)                ;
  ...


      问题出在代码中含有 bool 数据类型,C 不支持,C++ 支持。其实,这个问题很好解决,只要把文件的扩展名从 ".c" 改成 ".cpp" 就可以了。
      我使用的编译器和你的完全一样,你可以试试看。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-16 10:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表