一道笔试题,大家来看看哈

Aaron_Jerry 2007-10-23 12:24:45
下面是一个字符串安全拷贝的函数,请指出其中的错误。
char *j1_strncpy(char *dest,const char *src,size_t n)
{
char *d,*end;
if(0==n)
return (dest);
d=dest;
end=dest+n;
for(;d<end;d++,src++)
if(!(*d=*src))
return (d);
*d='\0';
return (d);
}
...全文
1352 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
dj3141592653 2007-11-16
  • 打赏
  • 举报
回复
/*** vc7.1下的源代码
*strncpy.c - copy at most n characters of string
*************************************************************/

#include <cruntime.h>
#include <string.h>

char * __cdecl strncpy (
char * dest,
const char * source,
size_t count
)
{
char *start = dest;

while (count && (*dest++ = *source++)) /**//* copy string */
count--;

if (count)
/**//* pad out with zeroes */
while (--count)
*dest++ = '\0 ';

return(start);
}
hnsdxujunyi06 2007-11-07
  • 打赏
  • 举报
回复
今天再过来看看,
我在库源文件里头看到的源代码,
比如完整代码:

// 20071107.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
//#include <iostream.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
char* csource = new char[20];
char* dsource = new char[15];
csource = "0123456789123456789";

//char* p_source = csource;



strncpy( dsource, csource, 25 );
cout<< dsource << endl;
cout << " "<< endl;


return 0;
}

char * __cdecl strncpy (
char * dest,
const char * source,
size_t count
)
{
char *start = dest;

while (count && (*dest++ = *source++)) /* copy string */
count--;

if (count) /* pad out with zeroes */
while (--count)
*dest++ = '\0';

return(start);
}
运行的实际效果是:
尽管目标字符数组长度一开始是15 < 20,
最后得到的输出结果却是0123456789123456789,
即目标字符数组长度大小被改变了!
wangzai117 2007-10-25
  • 打赏
  • 举报
回复
char *j1_strncpy(char *dest,const char *src,size_t n)
{
char *d,*end;
if(0==n)
return (dest);
d=dest;
end=dest+n;
for(;d <end;d++,src++)
if(!(*dest=*src)) // 改
return (dest); // 改
*d= '\0 ';
return (dest); // 改
}
gerry2000 2007-10-25
  • 打赏
  • 举报
回复
mark
jayskycai 2007-10-25
  • 打赏
  • 举报
回复
1:d为局部变量 返回d后 d被注销 所以函数返回值不确定 达不到预期效果
2:其他问题都是小问题
lovelyday 2007-10-25
  • 打赏
  • 举报
回复
晕~,看来这段程序一般情况下没问题的
LZ所说的三种情况
1.没有检查src为空的情况。
2.dest空间大小 < n 的情况没有考虑,end=dest+n存在越界访问带来的安全问题
3.返回值 return (d),没有实际意义,应返回 (dest)。
1,可能
2,只要dest空间大小 > n应该不会有越界问题,for中d<end,循环中d只会到dest+n-1
3,没有意义,但结果正确
lovelyday 2007-10-25
  • 打赏
  • 举报
回复
只看出了一个问题,改后程序正常
char *j1_strncpy(char *dest,const char *src,size_t n)
{
char *d,*end;
if(0==n)
return (dest);
d=dest;
end=dest+n;
for(;d <end;d++,src++)
if(!(*d=*src))
return (d);
*d= '\0'; //源程序此处为'\0 '多了一个空格键
return (d);
}
hnsdxujunyi06 2007-10-24
  • 打赏
  • 举报
回复
打列源文件,从.NET 2003 安装文件夹下找到的
文件路径:\Microsoft Visual Studio .NET 2003\Vc7\crt\src
文件名:strncpy.c
文件内容:
/***
*strncpy.c - copy at most n characters of string
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines strncpy() - copy at most n characters of string
*
*******************************************************************************/

#include <cruntime.h>
#include <string.h>

/***
*char *strncpy(dest, source, count) - copy at most n characters
*
*Purpose:
* Copies count characters from the source string to the
* destination. If count is less than the length of source,
* NO NULL CHARACTER is put onto the end of the copied string.
* If count is greater than the length of sources, dest is padded
* with null characters to length count.
*
*
*Entry:
* char *dest - pointer to destination
* char *source - source string for copy
* unsigned count - max number of characters to copy
*
*Exit:
* returns dest
*
*Exceptions:
*
*******************************************************************************/

char * __cdecl strncpy (
char * dest,
const char * source,
size_t count
)
{
char *start = dest;

while (count && (*dest++ = *source++)) /* copy string */
count--;

if (count) /* pad out with zeroes */
while (--count)
*dest++ = '\0';

return(start);
}
hnsdxujunyi06 2007-10-24
  • 打赏
  • 举报
回复
大家不如看看 C库 strncpy 函数里头的源代码,
对比一下,一切就都知道了,
呵呵。
xkw365 2007-10-24
  • 打赏
  • 举报
回复
把我以前的修改一下
char *j1_strncpy(char *dest,const char *src,size_t n)
{
char *d,*end;
if(n==0 ¦ ¦!dest||!src) //得判断dest,src是否为null
return (dest);
d=dest;
end=dest+n;
for(;d <end;d++,src++)
{
if(!(* d=* src))
return (dest);
}
*d= '\0 ';
return (d-n);
}
以上功能dest的长度要大于 min( src的长度,n);才能正确引用
xkw365 2007-10-24
  • 打赏
  • 举报
回复
把我以前的修改一下
char *j1_strncpy(char *dest,const char *src,size_t n)
{
char *d,*end;
if(n==0||!dest) //得判断dest是否为null
return (dest);
d=dest;
end=dest+n;
for(;d <end;d++,src++)
{
if(!(* d=* src))
return (dest);
}
*d= '\0 ';
return (d-n);
}
以上功能dest的长度要大于 min( src的长度,n);才能正确引用
xkb_surfing 2007-10-24
  • 打赏
  • 举报
回复
char *j1_strncpy(char *dest,const char *src,size_t n)
{
char *d,*end;
if(0==n)
return (dest);
d=dest;
end=dest+n;
for(;d <end;d++,src++)
if(!(*d=*src))
return (dest); //change here
*d= '\0 ';
return (dest); //change here
}
if0000000 2007-10-24
  • 打赏
  • 举报
回复
> Chiyer兄说的没问题,为了保证dest串有 '\0 '字符终止,必须n-1;

> 我仔细考虑了一下,上面说的部分是对的,但是都不全面,我编译测试了一下,一下是终极正确方案:

> #include "stdafx.h"
> #include "iostream"
> using namespace std;

> char *j1_strncpy(char *dest,const char *src,size_t n)

Even the C library strncpy doesn't guarantee a NULL terminated array of characters in case strlen(src) lager than n.
if0000000 2007-10-24
  • 打赏
  • 举报
回复
present them with a new version of your own
if0000000 2007-10-24
  • 打赏
  • 举报
回复

/*******************************************************************************
* copy n characters in string src to dst.
******************************************************************************/

char *strncpy(char *dst, const char *src, size_t n)
{
char *p = dst;

while (n-- && (*dst++ = *src++))
;
return p;
}
星羽 2007-10-23
  • 打赏
  • 举报
回复
xugang_2001

-----------

好好想想在做结论

如果你觉得没问题,那你试试


int main()
{
char* s = "hello world";
char d[5];

j1_strncpy(d, s, sizeof(d));

cout<<d<<endl;
return 0;
}
proware 2007-10-23
  • 打赏
  • 举报
回复
嗯,是,一楼的越改越错.
程序分为源串比目的空间短和长两种情况.
如果是源串短,if成立,从if下的return返回.
如果是源串长,那么d已经指向最后一个空间,而此时再*d= '\0 '; 会覆盖到后面的空间.
所以按照4楼改的就好了.
_石头_ 2007-10-23
  • 打赏
  • 举报
回复
^_^ 开始那个没有错----我边吃饭边看的,没注意!

for(;d <end;d++,src++)
if(!(*d=*src))
return (d);
*d= '\0 ';
return (d);

改成:
for(;d <=end;d++,src++)
if(!(*d=*src))
return (d);
*d= '\0 ';
d-=n;
return (d);
xugang_2001 2007-10-23
  • 打赏
  • 举报
回复
楼上似乎不对,end=dest+n没有问题,因为d<end时d最大为dest+n-1,所以没有问题,这个程序问题在return上,return (d),此时的d已经d++过n次了,不是原来的dest,所以应该return dest才对
星羽 2007-10-23
  • 打赏
  • 举报
回复


end=dest+n;
改成
end=dest+n-1;
加载更多回复(20)

69,375

社区成员

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

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