Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Strncpy只能与固定长度数组一起使用_C++_C_Strcpy_Strncpy - Fatal编程技术网

C++ Strncpy只能与固定长度数组一起使用

C++ Strncpy只能与固定长度数组一起使用,c++,c,strcpy,strncpy,C++,C,Strcpy,Strncpy,根据StackOverflow注释,strncpy不应与非固定长度数组一起使用 除非在结构/二进制文件中使用固定宽度、不一定以字符串结尾的字段,否则绝对不能使用strncpyR2012年1月11日16:22 我理解,如果您为字符串动态分配内存,这是多余的,但是否有理由认为在strcpy上使用strncpy不好呢?反对使用strncpy的理由是,它不能保证字符串将以null结尾 在使用非固定长度数组时,在C中复制字符串的一种不太容易出错的方法是使用它来保证字符串的null终止 对*n*函数的良好注

根据StackOverflow注释,strncpy不应与非固定长度数组一起使用

除非在结构/二进制文件中使用固定宽度、不一定以字符串结尾的字段,否则绝对不能使用strncpyR2012年1月11日16:22


我理解,如果您为字符串动态分配内存,这是多余的,但是否有理由认为在strcpy上使用strncpy不好呢?反对使用strncpy的理由是,它不能保证字符串将以null结尾

在使用非固定长度数组时,在C中复制字符串的一种不太容易出错的方法是使用它来保证字符串的null终止

对*n*函数的良好注释

这些函数允许您指定缓冲区的大小,但——这一点非常重要——它们不保证空终止。如果您要求这些函数写入的字符数超过将填充缓冲区的字符数,则它们将停止—从而避免缓冲区溢出—但它们不会为null—终止缓冲区


这意味着在不处理固定数组时使用strncpy和其他类似函数会带来不必要的非空终止字符串的风险,这些字符串可能会成为代码中的定时炸弹。

反对使用的理由是,它不能保证字符串将以空终止

在使用非固定长度数组时,在C中复制字符串的一种不太容易出错的方法是使用它来保证字符串的null终止

对*n*函数的良好注释

这些函数允许您指定缓冲区的大小,但——这一点非常重要——它们不保证空终止。如果您要求这些函数写入的字符数超过将填充缓冲区的字符数,则它们将停止—从而避免缓冲区溢出—但它们不会为null—终止缓冲区

这意味着在不处理固定数组时使用strncpy和其他类似函数会带来不必要的风险,即非空终止字符串可能会成为代码中的定时炸弹。

strncpy将复制数据,直到您指定的限制,但如果它在字符串结束之前达到该限制,它将使目的地未确定

换句话说,strncpy有两种可能。一个是,您得到的行为与strcpy所产生的行为完全相同,只是速度较慢,因为它用NUL填充了目标缓冲区的其余部分,而实际上您根本不需要或关心NUL。另一个原因是,它产生的结果通常无法用于任何实际用途

如果要将最大长度的字符串复制到固定长度缓冲区中,可以使用sprintf执行以下操作:

char buffer[256];

sprintf(buffer, "%255s", source);
与strncpy不同,这个始终为零终止结果,因此结果始终可用作字符串

如果您不想使用sprintf或类似的工具,我建议您只编写一个函数,它实际上可以实现您想要的功能,一般顺序如下:

void copy_string(char const *dest, char const *source, size_t max_len) { 
    size_t i;
    for (i=0; i<max_len-1 && source[i]; i++)
        dest[i] = source[i];
    dest[i] = '\0';
}
这仅在目标是实际数组而不是指针时有效,但在这种情况下,它让编译器推断数组的大小,而不是要求用户显式地传递它。这通常会使代码更快一点,减少函数调用中的开销,并且更难出错和传递错误的大小。

strncpy会将数据复制到您指定的限制,但如果在字符串结尾之前达到该限制,则会使目标未终止

换句话说,strncpy有两种可能。一个是,您得到的行为与strcpy所产生的行为完全相同,只是速度较慢,因为它用NUL填充了目标缓冲区的其余部分,而实际上您根本不需要或关心NUL。另一个原因是,它产生的结果通常无法用于任何实际用途

如果要将最大长度的字符串复制到固定长度缓冲区中,可以使用sprintf执行以下操作:

char buffer[256];

sprintf(buffer, "%255s", source);
与strncpy不同,这个始终为零终止结果,因此结果始终可用作字符串

如果您不想使用sprintf或类似的工具,我建议您只编写一个函数,它实际上可以实现您想要的功能,一般顺序如下:

void copy_string(char const *dest, char const *source, size_t max_len) { 
    size_t i;
    for (i=0; i<max_len-1 && source[i]; i++)
        dest[i] = source[i];
    dest[i] = '\0';
}
这仅在目标是实际数组而不是指针时有效,但在这种情况下,它让编译器推断数组的大小,而不是要求用户显式地传递它。这通常会使代码更快一点,减少函数调用的开销,更难出错并传递错误的大小。

char*strncpy char*destination,const char*source,size\t num

strncpy的局限性:

如果目标字符串已完全填充,则不会在其上放置空终止符。并且,如果源长度大于num,则不会在目标的末尾隐式追加空字符。 如果num大于l 源字符串的长度,目标字符串用空字符填充,最大长度为num。 与strcpy一样,它不是内存安全的操作。因为它在复制源之前并没有检查目标中是否有足够的空间,所以这是导致缓冲区溢出的潜在原因

请参阅:

char*strncpy char*目的地、常量char*源、大小\u t num

strncpy的局限性:

如果目标字符串已完全填充,则不会在其上放置空终止符。并且,如果源长度大于num,则不会在目标的末尾隐式追加空字符。 如果num大于源字符串的长度,则目标字符串将填充最大为num length的空字符。 与strcpy一样,它不是内存安全的操作。因为它在复制源之前并没有检查目标中是否有足够的空间,所以这是导致缓冲区溢出的潜在原因


请参阅:

我们有两个版本用于将字符串从一个复制到另一个 1> strcpy 2> strncpy
这两个版本用于固定和非固定长度数组。复制字符串时,strcpy不检查目标字符串的上限,strncpy将检查它。当目标字符串到达此上限时,函数strncpy将返回错误代码,同时函数strcpy将在当前进程的内存中造成一些影响,并立即终止进程。因此strncpy比strcpy更安全

我们有两个版本用于将字符串从一个复制到另一个 1> strcpy 2> strncpy
这两个版本用于固定和非固定长度数组。复制字符串时,strcpy不检查目标字符串的上限,strncpy将检查它。当目标字符串到达此上限时,函数strncpy将返回错误代码,同时函数strcpy将在当前进程的内存中造成一些影响,并立即终止进程。因此,strncpy比strcpy更安全

您可以在这里找到答案,原因是它没有做您认为它做的事情。您不应该出于任何目的使用strncpy,它本质上是不安全的。相反,请将strcpy与缓冲区大小检查一起使用。@Lundin:对于需要容纳4或8个字符的固定长度字段的结构来说,这种情况并不少见。任何坚持应用零终止的方法都将限制为3或7个字符,或者需要将字符串复制到外部缓冲区,然后使用memcpy存储它。如果一个结构包含一个char[8],并且有必要将其初始化为Hello,我认为strncpything.name,Hello,8;比memcpything.name更干净、更不易碎,Hello\0\0,8@超级cat初始化结构:type\u t type={.str=Hello};。运行时分配一个结构:type=type{.str=Hello};。这与strncpy没有多大关系,它仍然是一个危险的、过时的函数,仅用于Unix中的古老字符串类型。您可能会在这里找到答案,原因是它不符合您的想法。您永远不应该出于任何目的使用strncpy,它本质上是不安全的。相反,请将strcpy与缓冲区大小检查一起使用。@Lundin:对于需要容纳4或8个字符的固定长度字段的结构来说,这种情况并不少见。任何坚持应用零终止的方法都将限制为3或7个字符,或者需要将字符串复制到外部缓冲区,然后使用memcpy存储它。如果一个结构包含一个char[8],并且有必要将其初始化为Hello,我认为strncpything.name,Hello,8;比memcpything.name更干净、更不易碎,Hello\0\0,8@超级cat初始化结构:type\u t type={.str=Hello};。运行时分配一个结构:type=type{.str=Hello};。这与strncpy没有多大关系,它仍然是一个危险的、过时的函数,仅用于Unix中的古老字符串类型。不太容易出错-为true,但正确检查输出是否完整仍然很难看:int n=snprintfbuffer,缓冲区大小,%s,source;assertn>=0&&n=0&&n进行数组访问,您还可以访问写入的字符数。是的-大致风格和具体情况-例如,反n可能有用,如果不需要,它可能会弄乱您的本地符号,并且您可以快速处理n2、n3或o、p,或者使用更详细的字符,您也可以手动将其空终止:strncpydest,source,size-1;dest[size]=“0”;。也许不那么优雅,但我更喜欢它sprintf@AndreiR.:很好,一般来说这是经常做的,但是dest[大小]-@AndreiR.:答案中增加了备选方案。看来我一直在以char dest[256]的身份做这件事;如果我正在处理的代码部分中有snprintfdest,256,值:%s,source>=256{\\do error-migration}。我只是有点困惑,因为我一直在寻找一个坏的strcpy导致的错误,我的睡眠剥夺的大脑只是把它改成strncpy,认为它可以解决它,但它没有,我继续大惊小怪,试图找出我以前的逻辑是否都错了。你也可以手动终止它:strncpydest,来源,大小为1;dest[size]=“0”;。也许不那么优雅,但我更喜欢它sprintf@AndreiR.:很好,一般来说这是经常做的,但是dest[大小]-@AndreiR.:答案中增加了备选方案。看来我一直在以char dest[256]的身份做这件事;如果我正在处理的代码部分中有snprintfdest,256,值:%s,source>=256{\\do error-migration}。我只是有点困惑,因为我一直在寻找一个坏的strcpy导致的错误,我的睡眠剥夺的大脑把它改成了strncpy,认为它可以修复它,但它没有,我继续大惊小怪,试图找出我之前的逻辑是否都错了。特别是你最初用strncpy的奇怪措辞,该点和第一个点的起点显示为从。如果你确实使用了其他地方的东西,请引用,属性和链接到它。干杯。我在评论中提到了这个链接。顺便说一句,现在我在回答中也加了这个。谢谢特别是你最初的措辞古怪的strncpy,这和第一点的开始似乎被提了出来。如果你确实使用了其他地方的东西,请引用,属性和链接到它。干杯。我在评论中提到了这个链接。顺便说一句,现在我在回答中也加了这个。谢谢