首页
社区
课程
招聘
[求助]一个小c程序的疑问
发表于: 2007-9-8 13:28 7943

[求助]一个小c程序的疑问

2007-9-8 13:28
7943
#include<stdio.h>
#include<ctype.h>

int check(int n)
{
        if(isalpha(n))
        {
                printf("Please input num !!!\n");
                return 1;
        }
        if(!(n<=9 && n>=0))
        {
                printf("The num must between 0-9\n ");
                return 1;
        }
        printf("OK...\n");
        return 0;
}

int main()
{
        //init the arrays
        int num1,num2,i,n,sum[10][10];
        for (i=0;i<10;i++)
        {
                for (n=0;n<10;n++)
                        sum[i][n]=i+n;
        }
       
        printf("Please input the first num:");
        scanf("%d",&num1);
        if(check(num1))
                return -1;

        printf("Please input the second num:");
        scanf("%d",&num2);
        if(check(num2))
                return -1;

        printf("The sum of two is :%d \n",sum[num1][num2]);
        return -1;
}

源程序如上
现在不考虑程序的实现方法以及效率(原因:老师要求这样写的)
调试程序时发现:
如果输入字符的话(e.g:'a')
程序直接报错
希望知道原由的给小弟解释下
thax:)

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
免费
支持
分享
最新回复 (19)
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
2
int isalpha(
   int c
);

When used with a debug CRT library, isalpha will display a CRT assert if passed a parameter that is not EOF or in the range of 0 through 0xFF. When used with a release CRT library, isalpha will use the parameter as an index into an array, with undefined results if the parameter is not EOF or in the range of 0 through 0xFF.

说得很明确。
2007-9-8 15:06
0
雪    币: 13777
活跃值: (4752)
能力值: ( LV15,RANK:1673 )
在线值:
发帖
回帖
粉丝
3
程序本身就有问题

scanf("%d",&num1);

num1要不没读到,要不就读的数字,怎么还用isalpha(n) 呢?
2007-9-8 15:22
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
4
如何删除自己的回复????
2007-9-8 16:12
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
5
如何删除自己的回复~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2007-9-8 16:18
0
雪    币: 171
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
ps:
how do you find that txt?
2007-9-8 16:52
0
雪    币: 171
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
恩 是的
在scanf语句
如果输入的不是int型数据的话
那么输入的数拒根本就写不到num1里面去的
此时 num1为局部变量
取值不确定 应该为一个随即数
但是传给后面的isalpha作为参数时也不该出现错误的啊??????

thax AloneWolf,foxabu,wHt [aogo] 指点
2007-9-8 16:56
0
雪    币: 13777
活跃值: (4752)
能力值: ( LV15,RANK:1673 )
在线值:
发帖
回帖
粉丝
8
不知道你出错的提示是什么?
是变量没赋值?还是别的.

再说了你的 isalpha(n)
N只是对一个字母的ASCII码测试,你的方式根本没用.就算你输入的是个数字,用 isalpha(n) 来测试还是不对,差一个'0',也就是48,除非你的输入是48到57才会通过你的Check函数,不过这时数组应该越界了.
若一定要测试,那应该改成Scanf %c 而且改为
printf("The sum of two is :%d \n",sum[num1-'0'][num2-'0']);
2007-9-8 17:18
0
雪    币: 171
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
查了下msdn里面的关于isalpha函数的说明文档,似乎都没有说明这些,
我在测试测试,谢谢AloneWolf再次指点
下面附上报错截图(来的很干脆,总觉的有些蹊跷):
上传的附件:
2007-9-9 08:11
0
雪    币: 431
活跃值: (482)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
10
输入'a'后 NUM1的值为:-858993460

你说能不出错吗?

从根本上来说.你输入字符后,SCANF函数本身就执行失败了.你的check函数访问的是无效地址,自然会出错。这里强调的是你访问的地址是不是有效,而不是你那无效地址里存放的是什么东西.
2007-9-9 10:58
0
雪    币: 13777
活跃值: (4752)
能力值: ( LV15,RANK:1673 )
在线值:
发帖
回帖
粉丝
11
isalpha(n) 是多余的
之前偶看成 isdigit 了
不过从程序上看似乎运行程序时的确不会出错(非法)?
2007-9-9 11:20
0
雪    币: 30006
活跃值: (8499)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
12
2楼已经说了,反汇编一下可以看到在isalpha()处出错
2007-9-9 12:07
0
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
13
ctype是数组实现的, 范围默认是unsigned char, 0x0-0xff.
源代码在
crt\src\ctype.c
const unsigned short _wctype[] = {...};

int 参数作为数组下标传入, 比如你这个错误的临时变量num1,
isalpha(num1)
假设num1是0xcccccccc, 数组越界,此内存地址为windows系统保留地址,不可访问。

你可以尝试用
__try {
//你的代码

}
__except (EXCEPTION_EXECUTE_HANDLER) {
//捕获异常
}
2007-9-10 15:43
0
雪    币: 171
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
你的check函数访问的是无效地址,自然会出错。
---------------------------------
请问:这里的无效地址你是指什么地址 ?

check(n) ==> push n               ;单纯的看这里:个人理解这个n为立即数寻址,根本没地址而言。在程序中应该是去读取num1的地址进而得到里面的内容。
           call check

如果这里的无效地址你是指num1的地址,因为num1的地址是程序编译时就分配过的,即使scanf函数没能正确执行,但是俺认为这个和num1的地址也一点瓜葛也没有...

错误之处
还请Vegeta指教 :)
2007-9-10 19:32
0
雪    币: 171
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
只要输入字符型数据
很干脆的出错
....
郁闷,偶的调试技术。。。。
努力中....
2007-9-10 19:37
0
雪    币: 171
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
[QUOTE=readyu;358037]ctype是数组实现的, 范围默认是unsigned char, 0x0-0xff.
源代码在
crt\src\ctype.c
const unsigned short _wctype[] = {...};

int 参数作为数组下标传入, 比如你这个错误的临时变量num1,
isalpha(num...[/QUOTE]

感谢readyu指点
小弟是新手。。。
关于后面的调试技术您能否说的详细些?
如果嫌麻烦的话 就给我推荐些材料
偶自己看去
呵呵
2007-9-10 19:49
0
雪    币: 431
活跃值: (482)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
17
00401141  CMP DWORD PTR DS:[407564],1
00401148  JLE SHORT test.0040115B
0040114A  PUSH 103
0040114F  PUSH DWORD PTR SS:[ESP+8]
00401153  CALL test.00401C63
00401158  POP ECX
00401159  POP ECX
0040115A  RETN
0040115B  MOV EAX,DWORD PTR SS:[ESP+4]
0040115F  MOV ECX,DWORD PTR DS:[407358]
00401165  MOV AX,WORD PTR DS:[ECX+EAX*2]---->正常情况下EAX中存放输入的数值。
00401169  AND EAX,103
0040116E  RETN

如果前面的SCANF函数执行失败,那么EAX中就不是正常的值了。在我这里是“20202020”,那么——
DS:[ECX+EAX*2]成为:DS:[40404040+ECX],你说这地址对吗?
2007-9-12 15:40
0
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
18
异常处理,可以参看:
Programming Applications for Microsoft Windows
Jeffrey Richter
第五部分 结构化异常处理

电子版(翻译版):
http://www.czvc.com/tech/Windows%20HXBC/index.htm
2007-9-12 15:52
0
雪    币: 171
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
[QUOTE=Vegeta;358887]00401141  CMP DWORD PTR DS:[407564],1
00401148  JLE SHORT test.0040115B
0040114A  PUSH 103
0040114F  PUSH DWORD PTR SS:[ESP+8]
00401153  CALL test...[/QUOTE]


呵呵 明白了  
2007-9-17 19:32
0
雪    币: 171
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
谢谢 readyu
2007-9-17 19:32
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册