这是在 20CN网络安全小组第一代论坛 的论坛 编程破解 中的主题 请各位大哥挑一下这个程序的毛病?


要查看这个主题,请使用这个 URL:
http://www.20cn.net/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic;f=5;t=000215

disguise 发表于 :
 
# include<string.h>
# include<stdio.h>
check(p1,p2,compare)
char *p1,*p2;
int (*compare)();
{
if(!(*compare)(p1,p2))
printf("\n The two strings are equal!");
else
printf("\n The two strings are not equal!");
}
numcmp(a,b)
char *a,*b;
{
if(atoi(a)==atoi(b))
return(0);
else
return(1);
}
main()
{
int strcmp(),numcmp();
char str1[100],str2[100];
printf("\n Please enter two strings or numbers:");
scanf("%s",str1);
scanf("%s",str2);
printf("\n Please enter 'n' for number compare or enter 'c' for strings compare:");
if(getchar()=='n')
check(str1,str2,numcmp);
else
check(str1,str2,strcmp);
}

这个程序的题目:检查两个输入数或字符串是否相等。
其中
numcmp(a,b)
char *a,*b;
{
if(atoi(a)==atoi(b))
return(0);
else
return(1);
}
这是一段数比较函数,那么a,b都应该是数,比方说一个2,一个3,为什么这两个又是指针?那么atoi(a)的意思,
就是把a指针所指的那个数变换,然后进行比较。可是a并没有所指的数呀?
况且这是数的比较,为什么要用atoi函数(字符转数字)?
还有,整个程序运行不能正确运行,估计是
main()
{
int strcmp(),numcmp();
char str1[100],str2[100];
printf("\n Please enter two strings or numbers:");
scanf("%s",str1);
scanf("%s",str2);
printf("\n Please enter 'n' for number compare or enter 'c' for strings compare:");
if(getchar()=='n')
check(str1,str2,numcmp);
else
check(str1,str2,strcmp);
}
这一段的毛病,
printf("\n Please enter 'n' for number compare or enter 'c' for strings compare:");
if(getchar()=='n')
根本就没有机会输入n or c?
请各位大哥挑一下这个程序的毛病?
 


古老传说 发表于 :
 
scanf("%s",str);以后最后一个字符后面会多添加上一个\n,比如输入2 3<回车>,最后的字符串结果就是2 3\n\n,而getchar()发现有多余字符\n就不再要求用户去输入字符了,而\n表示一行输入的结束,所以getchar()就跳过了用户输入部分,getchar()返回的也应该是10('\n')

解决方法:在那个判断语句前面scanf后面插入一个getchar();

太困了,说得比较乱,抱歉
 


xiean 发表于 :
 
To: 古老传说
呵呵,不好意思,这个贴子我现在才细看,前几天没时间看,你解释的有点问题,我想指出一下

To: disguise
这个问题要先从几个函数讲起

getchar() getche() getch()

这三个函数的返回值都是一个字符,但效果并不同
getchar() 是从输入流读取一个字符
getche() 是从控制台获取一个字符且返回到输出设备,属于 conio.h
getch() 是从控制台获取一个字符但不返回到输出设备,属于 conio.h

下面是几个实例的回显
A. getchar()
Please input a char:y[Enter]
char is 'y'

B. getche()
Please input a char:y
char is 'y'

C. getch()
Please input a char:
char is 'y'

就输入时来说,getchar() 必须等待一个回车符才能开始处理并返回输入字串的第一个字符,而 getche() 和 getch() 则只接收控制台返回的一个字符就处理,这其中是不同的,在此例中,用上 getche() 来替换 getchar() 才是正确的做法,你可以试试。

如果你的 getchar() 放在 scanf() 前面的话将不会出现此类问题,而为什么放在后面会出现问题呢?原因是在 scanf 这个函数

...
char test[100];
scanf("%s", &test);

当我们输入字串 123 后,输入流(stdin)如下

stdin: [1] [2] [3] [\n] (M$)
stdin: [1] [2] [3] [\r] [\n] (Unix)

当 scanf() 运行后,把输入流和 test 字串如下
stdin: \n (M$)
stdin: \r\n (Unix)
test: [1] [2] [3] [\0]

这时你使用了 getchar(),但 getchar() 将先判断输入流中是否存在行结束符(在 M$ 里是 \n,在 Unix 里是 \r\n),如果存在行结束符则返回第一个字符,此时已看出问题所在,这时输入流(stdin)存在行结束符,于是,getchar()返回第一个字符,在 M$ 下,此字符为 \n。
而如果你使用 getche() 或 getch() 却为什么不会发生这个问题呢?呵呵,这个问题你可以查阅一下资料,要是我什么都说了,相反你不会理解得很清楚,提示一下,这和键盘缓冲区,寄存器,堆栈等有关 ^_*

------------------
技术相关的不用找我,我是菜鸟;
空虚的美眉不用找我,我有女友;
无聊的大虾不用找我,我只发呆;
以上皆否的不用找我,我想清静!

[被 xiean 编辑过(日期 08-18-2001)]
 


xiean 发表于 :
 
---------------------
其中
numcmp(a,b)
char *a,*b;
{
if(atoi(a)==atoi(b))
return(0);
else
return(1);
}
这是一段数比较函数,那么a,b都应该是数,比方说一个2,一个3,为什么这两个又是指针?那么atoi(a)的意思,
就是把a指针所指的那个数变换,然后进行比较。可是a并没有所指的数呀?
况且这是数的比较,为什么要用atoi函数(字符转数字)?
---------------------
这是因为传入函数的 a, b 两个变量的值并不一定是整形量,如果在函数内定义成 numcmp(int a, int b),那么如果传过来的不是整型量则程序会出错甚至崩溃。a, b 两个变量是在

if(atoi(a)==atoi(b))

这句里转为整型量的,atoi(char *) 函数用于将字串转为整理量


另外,这段代码写得并不好,很多地方都可以找出问题,照这种代码学语言有时会误解你的思路

------------------
技术相关的不用找我,我是菜鸟;
空虚的美眉不用找我,我有女友;
无聊的大虾不用找我,我只发呆;
以上皆否的不用找我,我想清静!
 


古老传说 发表于 :
 
To xiean:呵呵,刚刚我又看了一下,我也发现了我的错误(呵呵,原来只一味的看汇编有时更误事,也许是我的汇编实在太菜 ),见笑了,只是还不明白scanf为什么要在输入的行尾加上两个\n呢(以至于当初看错了一个字节误以为getchar()是读取的后面一个\n)?这样做又有什么好处?
(我是用vc6.0调试的)
 
disguise 发表于 :
 
numcmp(a,b)
char *a,*b;
{
if(atoi(a)==atoi(b))
return(0);
else
return(1);
}
其中
char *a,*b;
为什么是指针?是不是函数的变量都是指针?
2 推荐一本c的好书?

 
disguise 发表于 :
 
结果,按古老传说的方法,问题解决了,可是还有问的?
1 古老传说说的
解决方法:在那个判断语句前面scanf后面插入一个getchar();
目的是不是把多出来的那个\n消耗掉?
2 scanf("%s",str1);
scanf("%s",str2);
printf("\n Please enter 'n' for number compare or enter 'c' for strings compare:");
if(getchar()=='n')
其中
if(getchar()=='n')并没有按回车呀,应该不处理才对吧?


 


风起 发表于 :
 
我说一句,我觉得用字符串的比较函数来完成这个工作会比较好一些。
1、先用程序看是不是数字,是的话用数字的方法来处理。
不是的话,再用字符串处理函数来处理。


2,你说的char *a,*b; 实际是这么回事,我觉得这个程序不是你编的,因为你能写出来,应该知道CHAR * A就是用来声明指针的,和是不是函数的变量没有什么关系。

 


disguise 发表于 :
 
你没说明白呀,和没说一样
果,按古老传说的方法,问题解决了,可是还有问的?
1 古老传说说的
解决方法:在那个判断语句前面scanf后面插入一个getchar();
目的是不是把多出来的那个\n消耗掉?
2 scanf("%s",str1);
scanf("%s",str2);
printf("\n Please enter 'n' for number compare or enter 'c' for strings compare:");
if(getchar()=='n')
其中
if(getchar()=='n')并没有按回车呀,应该不处理才对吧?

numcmp(a,b)
char *a,*b;
{
if(atoi(a)==atoi(b))
return(0);
else
return(1);
}
其中
char *a,*b;
为什么是指针?是不是函数的变量都是指针?为什么不直接用a,b?


 


风起 发表于 :
 

如果是在MAIN主函数中要调用子函数的话,必须在程序的开头要声明函数的参数的调用类型,也就是说,
如果要调用一个CMP函数的话,并且这个给CMP子函数的参数是两个字符串指针,你必须在程序开头这样来声明.
CHAR CMP(CHAR * A,CHAR * B)
前面的CHAR无关紧要,也可以改成其它的.比如说你想返回值是真或者是假,就可以改为整型的变量声明.关键是后面的A 和B 的形参一定要是有CHAR的,这样才是声明了子函数是用字符串指针来作实参的.也就是说可以用CMP来比较字符串.


你说的那个关于的问题,在实际中,你的那一段程序的代码已经执行了,只不过你在程序设计中思路不完善,没有错误思路和考虑.

在if(getchar()=='n')
check(str1,str2,numcmp);
else
check(str1,str2,strcmp);
}
这个代码里面,你应该用一个循环来控制,再考虑输入的其它情况,和执行程序的人不按你安排的情况来以后给他的提示,以及回到他操作错误前的那个断点的跳回代码.

不好意思,上次没有来得及给你说清楚,实在是抱歉,我现在学程序设计也少多了,可能说错了.

我的EMAIL:ylb2000@263.net

 


disguise 发表于 :
 
现在我不明白的只有
if(getchar()=='n')这个语句是否执行getchar()一遍?
还是只是把getchar()当成一个变量,判断它的值而已?
 
huang 发表于 :
 
那个语句if(getchar()=='n')就是一个判断的语句,只能执行一次呀!不过人们把这个语句嵌套在一个循环的语句中运行的!从而进行多次判断的!这样做是很有用的噢!

------------------
我就是我!只有我才能找回我自己!一个男孩子的话——huang的!

[被 huang 编辑过(日期 08-19-2001)]
 






Powered by Infopop Corporation
UBB.classic™ 6.5.0
NetDemon修改版 1.5.0, 20CN网络安全小组 版权所有。