关于strncpy的一个奇怪的问题

cgch_cn 2011-01-01 10:19:50
最近在使用strncpy的时候翻看谭浩强的《C程序设计(第四版)》,在163页说明的第(5)条看到一段话,意思是说,在使用strncpy(str1,str2,n)的时候,n不能超过str1中的字符个数。比如有如下程序:

char str1[10]={"China"},str2[]={"republic of China"};
strncpy(str1,str2,n);
printf("%s",str1);

则第二句中的n要求不能超过5.
但是,在上述程序中将n改为比5大的数的时候程序照样运行,并输出正确结果。
问题是:
是不是在strncpy(str1,str2,n)中只要n不超过str1的元素个数即可,如上例,n不超过10就行,是不是这样?恳请高手指点。
...全文
435 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
jingavin0 2011-08-05
  • 打赏
  • 举报
回复
其实strncpy(str1,str2,n)里面,n是控制复制数量的,n只要不超过str1的长度就行了,不过考虑到str1是字符串,所以n最多等于str1-1,最后要预留一个'\0'的结束符,如果str1有指针移位的话,n的最大值也要做相应的调整,str2指针移位就每什么打的关系了,因为这函数复制到'\0'就结束了,和n的数值没大的关系
cgch_cn 2011-01-03
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 matrixcl 的回复:]
引用 3 楼 sjh86126 的回复:
你那个是将str2中的元素向str1中copy,lz先要弄清顺序啊。。。。

另外来说,n是不能超过5个的,当然如果超过5个也会打印出来(即人们常说的偷内存),如果你偷的多了就会发生不可预知的错误。。。所以说还是要按原则来编写程序啊。。。


误人子弟啊.

str1分配的空间是10,所以n<=10, strncpy语句都正常。

但使……
[/Quote]
确实是只要n小于等于10 就行。
今天又看了书上的例6.9,也说明了这一点。
又:
我觉得matrixcl提到的问题很有道理,这是一个好习惯,个人感觉又双重保险的方法:
在声明字符数组的时候如果不直接赋值就将其初始化为全'\0'的数组;同时在使用strncpy的时候最后手动添加一个'\0'.

cgch_cn 2011-01-03
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 zhao4zhong1 的回复:]
strncpy, wcsncpy, _mbsncpy
Copy characters of one string to another.

char *strncpy( char *strDest, const char *strSource, size_t count );

wchar_t *wcsncpy( wchar_t *strDest, const wchar_t *strS……
[/Quote]
虽然没全看明白,但确实是很详细的解释,尤其是最后的例子,还学习了一个技巧:“ strncpy( string + 9, "mean", 4 );”原来在第一个参数上还可以做位移。
非常感谢!!
qa1112 2011-01-02
  • 打赏
  • 举报
回复
真是新年大礼
matrixcl 2011-01-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sjh86126 的回复:]
你那个是将str2中的元素向str1中copy,lz先要弄清顺序啊。。。。

另外来说,n是不能超过5个的,当然如果超过5个也会打印出来(即人们常说的偷内存),如果你偷的多了就会发生不可预知的错误。。。所以说还是要按原则来编写程序啊。。。
[/Quote]

误人子弟啊.

str1分配的空间是10,所以n<=10, strncpy语句都正常。

但使用strncpy还有一点需要注意,这里的n是不包括结束符'\0'的, strncpy也不会添加'\0'.
所以后面使用这个str1可能会出问题.
一般做法是拷贝size-1个字符, 再手动添加'\0'

char str1[10]={"China"},str2[]={"republic of China"};
strncpy(str1,str2,9);
str1[9] = '\0';
printf("%s",str1);



macro_lu 2011-01-02
  • 打赏
  • 举报
回复
这个数和STR1 STR2 都有关系吧
赵4老师 2011-01-02
  • 打赏
  • 举报
回复
strncpy, wcsncpy, _mbsncpy
Copy characters of one string to another.

char *strncpy( char *strDest, const char *strSource, size_t count );

wchar_t *wcsncpy( wchar_t *strDest, const wchar_t *strSource, size_t count );

unsigned char *_mbsncpy( unsigned char *strDest, const unsigned char *strSource, size_t count );

Routine Required Header Compatibility
strncpy <string.h> ANSI, Win 95, Win NT
wcsncpy <string.h> or <wchar.h> ANSI, Win 95, Win NT
_mbsncpy <mbstring.h> Win 95, Win NT


For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version
LIBCMT.LIB Multithread static library, retail version
MSVCRT.LIB Import library for MSVCRT.DLL, retail version


Return Value

Each of these functions returns strDest. No return value is reserved to indicate an error.

Parameters

strDest

Destination string

strSource

Source string

count

Number of characters to be copied

Remarks

The strncpy function copies the initial count characters of strSource to strDest and returns strDest. If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string. If count is greater than the length of strSource, the destination string is padded with null characters up to length count. The behavior of strncpy is undefined if the source and destination strings overlap.

wcsncpy and _mbsncpy are wide-character and multibyte-character versions of strncpy. The arguments and return value of wcsncpy and _mbsncpy vary accordingly. These three functions behave identically otherwise.

Generic-Text Routine Mappings

TCHAR.H Routine _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined
_tcsncpy strncpy _mbsnbcpy wcsncpy


Example

/* STRNCPY.C */

#include <string.h>
#include <stdio.h>

void main( void )
{
char string[100] = "Cats are nice usually";
printf ( "Before: %s\n", string );
strncpy( string, "Dogs", 4 );
strncpy( string + 9, "mean", 4 );
printf ( "After: %s\n", string );
}


Output

Before: Cats are nice usually
After: Dogs are mean usually

screwzm 2011-01-02
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hnuqinhuan 的回复:]

不超出你分配的空间就可以了
[/Quote]
+
cgch_cn 2011-01-01
  • 打赏
  • 举报
回复
回答的这么快!非常感谢各位。
但还没看明白
[Quote=引用 5 楼 hnuqinhuan 的回复:]
引用 3 楼 sjh86126 的回复:
你那个是将str2中的元素向str1中copy,lz先要弄清顺序啊。。。。

另外来说,n是不能超过5个的,当然如果超过5个也会打印出来(即人们常说的偷内存),如果你偷的多了就会发生不可预知的错误。。。所以说还是要按原则来编写程序啊。。。

但是再分配空间的时候已经分配分配10个空间 所以只要不超出10就可以了 否则就会有内存泄露的危险
[/Quote]
请问上面的叙述中偷内存和内存泄露是不是指由于对超出数组下标范围的元素赋值引起的内存溢出?
另外,本例中只要不超过9是不是就可以呢,因为还要在最后自动加一个'\0'。
再次表示感谢。
無_1024 2011-01-01
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sjh86126 的回复:]
你那个是将str2中的元素向str1中copy,lz先要弄清顺序啊。。。。

另外来说,n是不能超过5个的,当然如果超过5个也会打印出来(即人们常说的偷内存),如果你偷的多了就会发生不可预知的错误。。。所以说还是要按原则来编写程序啊。。。
[/Quote]
但是再分配空间的时候已经分配分配10个空间 所以只要不超出10就可以了 否则就会有内存泄露的危险
SwiftFun 2011-01-01
  • 打赏
  • 举报
回复
是的,不超过10就行。
墓后煮屎人 2011-01-01
  • 打赏
  • 举报
回复
你那个是将str2中的元素向str1中copy,lz先要弄清顺序啊。。。。

另外来说,n是不能超过5个的,当然如果超过5个也会打印出来(即人们常说的偷内存),如果你偷的多了就会发生不可预知的错误。。。所以说还是要按原则来编写程序啊。。。
無_1024 2011-01-01
  • 打赏
  • 举报
回复
不超出str1分配的空间就是可以copy的 当大于的时候就会出现溢出的错误
無_1024 2011-01-01
  • 打赏
  • 举报
回复
不超出你分配的空间就可以了

69,373

社区成员

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

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