为什么函数里面必须要printf输出一下,否则报 段错误?

leinchu 2009-12-20 11:55:22
我在网上找了个md5函数,自己改造了下,方便使用,结果很神奇的是,我传入的参数,必须要先printf打印一下,否则报:段错误;


我是在centos下面弄的,我改的代码部分如下:

……省略别人的代码……
char *
md5 (char *str)
{
struct cvs_MD5Context context;
unsigned char checksum[16];
int i,l;
char *rtn;
char buffer[32];
cvs_MD5Init (&context);
cvs_MD5Update (&context, str, strlen(str));
cvs_MD5Final (checksum, &context);
printf("got str=%s\n",str); //少了这句或者下面的一句都会报段错误,不理解,这是为什么?!
sprintf(buffer,'\0',str);

for (i = 0; i < 16; i++)
{
sprintf (buffer,"%s%02x",buffer,(unsigned int) checksum[i]);
}
strcpy(rtn,buffer);
return rtn;
}

int main(int argc, char **argv){
char *rtn;
rtn=md5("123qwe");
printf("2 rtn =%s\n",rtn);
return 0;
}


另外指针这个玩意儿,除了用 *p++这种方式外,还有什么方法移动到开头或者结尾,我都不知道问得对不对?
初学者,请赐教,万分感谢各位!!


...全文
819 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
leinchu 2009-12-21
  • 打赏
  • 举报
回复
再来一种:
char *
md5 (char *str)
{
struct cvs_MD5Context context;
unsigned char checksum[16];
int i;
char *rtn;
cvs_MD5Init (&context);
cvs_MD5Update (&context, str, strlen(str));
cvs_MD5Final (checksum, &context);
rtn=malloc(sizeof(char)*32);
for (i = 0; i < 16; i++)
{
//sprintf (rtn+i*2,"%02x",(unsigned int) checksum[i]);//这行和下面以行效果一样!
sprintf (rtn,"%s%02x",rtn,(unsigned int) checksum[i]);
}
return rtn;
}

int main(int argc, char **argv){
char *rtn;
rtn=md5("123qwe");
printf("2 rtn =%s\n",rtn);
return 0;
}
leinchu 2009-12-21
  • 打赏
  • 举报
回复
昏死,上面的红色的

其二:

位置没有摆对,应该在它下面的main下面。
leinchu 2009-12-21
  • 打赏
  • 举报
回复
To mstlq:
你的程序完全正确,这C好神奇啊, 就传个char rtn[33];进去,也不用&或者指针,就起到了按址传递的效果.搞不清楚哦!哎!

TO cattycat:
事实是,我就是用上面那段红色的代码就能达到效果,就是没分配内存,也不知道什么时候需要分配内存,分配内存有啥用.


根据两位的提示,我搞出来下面两种写法,都可以达到我想要得效果,至于标准不标准我就不知知道了:
其一:

char *
md5 (char *str)
{
struct cvs_MD5Context context;
unsigned char checksum[16];
int i,l;
char *rtn;
char buffer[33];
cvs_MD5Init (&context);
cvs_MD5Update (&context, str, strlen(str));
cvs_MD5Final (checksum, &context);

for (i = 0; i < 16; i++)
{
sprintf (buffer+i*2,"%02x",(unsigned int) checksum[i]);
}

rtn=strdup(buffer);
return rtn;
}


其二:

int main(int argc, char **argv){
char *rtn;
rtn=md5("123qwe");
printf("2 rtn =%s\n",rtn);
return 0;
}

char *
md5 (char *str)
{
struct cvs_MD5Context context;
unsigned char checksum[16];
int i,l;
char *rtn;
char buffer[33];
cvs_MD5Init (&context);
cvs_MD5Update (&context, str, strlen(str));
cvs_MD5Final (checksum, &context);

for (i = 0; i < 16; i++)
{
sprintf (buffer+i*2,"%02x",(unsigned int) checksum[i]);
}
rtn=malloc(sizeof(buffer));
strcpy(rtn,buffer);
return rtn;
}

int main(int argc, char **argv){
char *rtn;
rtn=md5("123qwe");
printf("2 rtn =%s\n",rtn);
return 0;
}
jackyjkchen 2009-12-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 jackyjkchen 的回复:]
sprintf(buffer,'\0',str);
还是这句的问题,你这句里,buffer只存进一个\0
[/Quote]
还不对,'\0'单引号……晕,能编译过?
jackyjkchen 2009-12-20
  • 打赏
  • 举报
回复
sprintf(buffer,'\0',str);
还是这句的问题,你这句里,buffer只存进一个\0
leinchu 2009-12-20
  • 打赏
  • 举报
回复
好感动,这么快就有回复了,谢谢各位。

补充一下我上面的代码是能按照预期运行的,只是少了红色的那两句(任意一句,或者两句)就会报错:段错误!

都说sprintf(buffer,'\0',str);这句说错的,但是少了这句执行的时候会报错;另外这句可以用:memset(buffer,'\0',1);代替。我就怀疑是不是sprintf或memset能把指针怎么动一动,不然为什么这句话必不可少。

(阿荣) 的话,我得在仔细试试,理解理解。我把"123qwe"放到char*变量里面去看看!
arong1234 2009-12-20
  • 打赏
  • 举报
回复
看下面注释:
[Quote=引用楼主 leinchu 的回复:]
char *
md5 (char *str) //这里需要得是一个可写得缓冲区,而你得输入实际是个常量字符串,不可写
{
        struct cvs_MD5Context context;
        unsigned char checksum[16];
        int i,l;
        char *rtn;//没有分配空间
        char buffer[32];
        cvs_MD5Init (&context);
        cvs_MD5Update (&context, str, strlen(str));
        cvs_MD5Final (checksum, &context);
       printf("got str=%s\n",str);            //少了这句或者下面的一句都会报段错误,不理解,这是为什么?!
        sprintf(buffer,'\0',str);
        for (i = 0; i < 16; i++)
        {
              sprintf (buffer,"%s%02x",buffer,(unsigned int) checksum[i]);
        }
        strcpy(rtn,buffer);
        return rtn;
}

int main(int argc, char **argv){
        char *rtn;
        rtn=md5("123qwe");//123qwe是常量字符串,你需要先分配缓冲,然后把它拷贝进去,不能直接传字符串
        printf("2 rtn  =%s\n",rtn);
        return 0;
}


另外指针这个玩意儿,除了用 *p++这种方式外,还有什么方法移动到开头或者结尾,我都不知道问得对不对?
初学者,请赐教,万分感谢各位!!


[/Quote]
kingteng 2009-12-20
  • 打赏
  • 举报
回复
你这个sprintf的用法不对
int sprintf ( char * str, const char * format, ... );
HelloDan 2009-12-20
  • 打赏
  • 举报
回复
sprintf(buffer,'\0',str);

这个东西好像本来就有问题啊。
arong1234 2009-12-20
  • 打赏
  • 举报
回复
指针没有指向开头或者结尾得方法,得你自己记住开头(用另外一个指针保存一下开头)和计算结尾(开头+长度就是结尾)

你这种错误怀疑你有内存访问越界,加一个printf问题就没有,只是一种假相而已。
cattycat 2009-12-20
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 mstlq 的回复:]
至少有一个低级错误……
C/C++ codechar*rtn;
………………
strcpy(rtn,buffer);
[/Quote]

对头, rtn没有分配空间,怎么向里边拷贝东西。
mstlq 2009-12-20
  • 打赏
  • 举报
回复

/*char * md5 (char *str)这种接口就很有问题*/
void md5 (char *str,char rtn[33])
{
struct cvs_MD5Context context;
unsigned char checksum[16];
int i,l;
cvs_MD5Init (&context);
cvs_MD5Update (&context, str, strlen(str));
cvs_MD5Final (checksum, &context);
for (i = 0; i < 16; i++)
{
sprintf (rtn+i*2,"%02x",(unsigned int) checksum[i]);
}
return ;
}

int main(int argc, char **argv){
char rtn[33];
md5("123qwe",rtn);
printf("2 rtn =%s\n",rtn);
return 0;
}
mstlq 2009-12-20
  • 打赏
  • 举报
回复
至少有一个低级错误……

char *rtn;
………………
strcpy(rtn,buffer);
hlyces 2009-12-20
  • 打赏
  • 举报
回复
sprintf (buffer,"%s%02x",buffer,(unsigned int) checksum[i]); //错误在这里,当你没做前面你加了红色的部分时,buffer是没内存的,所以错误。我想是不是你写错了???

第二个buffer
leinchu 2009-12-20
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 selooloo 的回复:]
cvs_MD5Update (&context, str, strlen(str));
这个函数有没有对str进行修改啊
[/Quote]

没明白你的意思,

现在最终改成这样的:

char *
md5 (char *str)
{
struct cvs_MD5Context context;
unsigned char checksum[16];
int i,l;
char *rtn;
char buffer[32];
cvs_MD5Init (&context);
cvs_MD5Update (&context, str, strlen(str));
cvs_MD5Final (checksum, &context);
printf("\0",str);

//sprintf(buffer,'\0');
memset(buffer,'\0',1);
for (i = 0; i < 16; i++)
{
sprintf (buffer,"%s%02x",buffer,(unsigned int) checksum[i]);
}
strcpy(rtn,buffer);
return rtn;
}

int main(int argc, char **argv){
char *rtn;
rtn=md5("123qwe");
printf("2 rtn =%s\n",rtn);
return 0;
}



不光
printf("\0",str);
memset(buffer,'\0',1);
这两句不能少,

连 int i,l;
这个多余的l都不能少, 这C也太tmd的神奇了嘛!!!


要疯了!!
selooloo 2009-12-20
  • 打赏
  • 举报
回复
cvs_MD5Update (&context, str, strlen(str));
这个函数有没有对str进行修改啊
leinchu 2009-12-20
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 selooloo 的回复:]
char str[]="123qwe";
str定义成这样看看
[/Quote]

不行,这样更不行,即使有 printf("got str=%s\n",str); sprintf(buffer,'\0',str); 这两句都还是会报段错误。
selooloo 2009-12-20
  • 打赏
  • 举报
回复
char str[]="123qwe";
str定义成这样看看
leinchu 2009-12-20
  • 打赏
  • 举报
回复
to:(阿荣),我改成下面的,没啥变化, printf("got str=%s\n",str);还是必不可少,可以改成 printf("\0",str);这样就没有实际的输出,不影响效果了,但是也还是很迷糊printf("\0",str);,为啥就不能少了。

int main(int argc, char **argv){
char *rtn,*str="123qwe";
rtn=md5(&*str);
printf("2 rtn =%s\n",rtn);
return 0;
}
cattycat 2009-12-20
  • 打赏
  • 举报
回复
写一个'\0',是表示结尾吧,还是感觉sprintf(buffer,'\0',str);这句有问题。
可能这里需要buffer初始化一下吧,所以你用memset也会行的,不然会造成后面数组访问越界。

70,028

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧