用getch()来替换scanf()
编写自定义整数输入函数函数原型为: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 本帖最后由 jackz007 于 2019-12-4 01:46 编辑
#include <stdio.h>
#include <conio.h>
inputInt(void)
{
char c , s ;
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 = 0x00 ;
m -- ;
}
} else {
s = c ;
printf("%c" , c) ;
}
}
printf("\n") ;
for(; (s == 0x09 || s == 0x20) && m > 0 ; s = 0) ;
for(e = 0 ; (s == 0x09 || s == 0x20) && e < m ; e ++) ;
for(k = e ; k < m + 1 ; k ++) s = s ;
m -= e ;
e = 0 ;
if(m > 0) {
if(m > 1 && s == '0' && (s == 'x' || s == 'X')) {
if(m > 2) {
for(f = true , k = 2 ; k < m && f ; k ++) {
if(s >= '0' && s <= '9') d = s - '0' ;
else if(s >= 'a' && s <= 'f') d = 10 + s - 'a' ;
else if(s >= 'A' && s <= 'F') d = 10 + s - 'A' ;
else f = false ;
if(f) e = e * 16 + d ;
}
if(! f) e = 0 ;
}
} else {
a = 0 ;
if(s == '-') a ++ ;
if(m > a) {
if(s != '0') {
for(f = true , k = a ; k < m && f ; k ++) {
if(s >= '0' && s <= '9') d = s - '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 字符。 for(; (s == 0x09 || s == 0x20) && m > 0 ; s = 0) ;
for(e = 0 ; (s == 0x09 || s == 0x20) && e < m ; e ++) ;
for(k = e ; k < m + 1 ; k ++) s = s ;代没太看懂了,可而且段代码在codeblocks编译通过不了,但还是很感谢!{:9_232:} 本帖最后由 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 = f;
putch(f);//回显
ct++;
char *tmp = (char *)malloc(sizeof(char) * (sz + ct));
tmp = '\0';
strcpy(tmp, str);
free(str);
str = tmp;
}
printf("\n");
char res;
res = '+';
res = '\0';
if (str == '-')
{
strcpy(res, str);
}
else
{
strcat(res, str);
}
free(str);
if (res == '+') //如果是正数
{
if (res == '0' && (res == 'x' || res == 'X')) //如果是16进制数
{
for (size_t i = 3; i < strlen(res); i++)
{
if (isdigit(res) || ((res >= 'a') && (res <= 'f')) || (res >= 'A' && res <= 'F'))
{
if (isupper(res))
{
res = (char)(58 + res - 'A');
}
else if (islower(res))
{
res = (char)(58 + res - 'a');
}
}
else
{
perror("ERROR");
exit(1);
}
result = result * 16 + (res - 48);
}
}
else //如果是10进制数
{
for (size_t i = 1; i < strlen(res); i++)
{
if (!isdigit(res))
{
perror("ERROR");
exit(1);
}
else
{
result = result * 10 + (res - 48);
}
}
}
}
else if (res == '-') //如果是负数
{
if (res == '0' && (res == 'x' || res == 'X')) //如果是16进制数
{
for (size_t i = 3; i < strlen(res); i++)
{
if (isdigit(res) || ((res >= 'a') && (res <= 'f')) || (res >= 'A' && res <= 'F'))
{
if (isupper(res))
{
res = (char)(58 + res - 'A');
}
else if (islower(res))
{
res = (char)(58 + res - 'a');
}
}
else
{
perror("ERROR");
exit(1);
}
result = result * 16 + (res - 48);
}
result = -result;
}
else //如果是10进制数
{
for (size_t i = 1; i < strlen(res); i++)
{
if (!isdigit(res))
{
perror("ERROR");
exit(1);
}
else
{
result = result * 10 + (res - 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> 本帖最后由 ba21 于 2019-12-4 17:32 编辑
jackz007 发表于 2019-12-4 01:30
编译运行实况:
发错对像
昨晚看了下,没完成,今 天又看了下,看楼上的代码实属高手看的代码,如 果不格式化好我是没法看下去。
所以我还是按我的思路搞了段代码,给参考下:
#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 = {'\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 = ch;
i++;
putch(ch); // 回显
}
else // 其它位
{
if ( num=='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 = ch;
i++;
putch(ch); // 回显
}
}
printf("\n");
/* 转换 */
if ( num=='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;
} 本帖最后由 jackz007 于 2019-12-4 18:37 编辑
Oxford 发表于 2019-12-4 12:16
for(; (s == 0x09 || s == 0x20) && m > 0 ; s = 0) ;
...
问题出在代码中含有 bool 数据类型,C 不支持,C++ 支持。其实,这个问题很好解决,只要把文件的扩展名从 ".c" 改成 ".cpp" 就可以了。
我使用的编译器和你的完全一样,你可以试试看。
页:
[1]