- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有以下模仿应用程序中代码的示例代码。
#include <iostream>
#include <string.h>
#include <cstring>
#include <atlstr.h>
using namespace std;
void test(char *s, int size)
{
//s = "";
int lens = strlen(s);
char *str1 = "(( State:0.000000 Std30c5 = State:T ) OR (( State:0.000000 Std30c6 = State:T ) OR (( State:0.000000 Std30c7 = State:T ) OR (( State:0.000000 Std30c8 = State:T ) OR (( State:0.000000 Std30c9 = State:T ) OR (( State:0.000000 Std30ca = State:T ) OR (( State:0.000000 Std30cb = State:T ) OR (( State:0.000000 Std30cc = State:T ) OR (( State:0.000000 Std30cd = State:T ) OR (( State:0.000000 Std30ce = State:T ) OR (( State:0.000000 Std30cf = State:T ) OR ( ...0.000000 = State:T ))))))))))))";
int len1 = strlen(str1);
strncpy(s, str1, 512);
int len = strlen(s);
}
int main()
{
char strDisplay[512] = "";
test(strDisplay, 512);
cout << strDisplay << endl;
system("pause");
return 0;
}
结果是:lenofstrtest = 523;lenofstr1 = 512;
strtest =“((状态:0.000000 Std30c5 =状态:T)或((状态:0.000000 Std30c6 =状态:T)或((状态:0.000000 Std30c7 =状态:T)或((状态:0.000000 Std30c8 =状态:T ) OR (( State:0.000000 Std30c9 = State:T ) OR (( State:0.000000 Std30ca = State:T ) OR (( State:0.000000 Std30cb = State:T ) OR (( State:0.000000 Std30cc = State:T ) 或 (( 州:0.000000 Std30cd = 州:T ) 或 (( 州:0.000000 Std30ce = 州:T ) 或 (( 州:0.000000 Std30cf = 州:T ) 或 ( ...0.000000 = 州:T ))) ))))))))ÌÌÌÌJ¢Š£øø)"
为什么 strncpy 复制额外的字符?
(这导致了一个问题,因为不正确的 strnlen 导致解包逻辑失控!)
我猜这与“strncpy 错误 512 字节”有关...请帮助我理解此错误。
最佳答案
strncpy
不会将终止字符“\0”添加到截断的字符串中,这会导致您遇到的问题。当字符串未正确终止时,它看起来更长,但您实际看到的是内存中缓冲区之后放置的数据。它可能会导致严重的问题。
您应该使用 strlcpy
而不是 strncpy
,它会正确终止字符串并返回源字符串的长度,您可以将其与缓冲区的长度进行比较以了解字符串是否被截断。 strncpy
返回指向缓冲区指针的指针(这不是很有用,因为您已经知道它 - 您将它作为第一个参数传递)并且不会告诉您是否发生了任何截断。
参见 man strlcpy:
The strlcpy() and strlcat() functions copy and concatenate strings with the same input parameters and output result as snprintf(3). They are designed to be safer, more consistent, and less error prone replacements for the easily misused functions strncpy(3) and strncat(3). strlcpy() and strlcat() take the full size of the destination buffer and guarantee NUL-termination if there is room. Note that room for the NUL should be included in dstsize.
和C string handling - Replacements在维基百科上:
The most popular[a] replacement are the strlcat and strlcpy functions, which appeared in OpenBSD 2.4 in December, 1998.[84] These functions always write one NUL to the destination buffer, truncating the result if necessary, and return the size of buffer that would be needed, which allows detection of the truncation and provides a size for creating a new buffer that will not truncate.
不幸的是,它不包含在 glibc 中 - 请参阅 Secure Portability纸达米安·米勒 (PDF):
The strlcpy and strlcat API properly check the target buffer’s bounds, nul-terminate in all cases and return the length of the source string, allowing detection of truncation. This API has been adopted by most modern operating systems and many standalone software packages, including OpenBSD (where it originated), Sun Solaris, FreeBSD, NetBSD, the Linux kernel, rsync and the GNOME project. The notable exception is the GNU standard C library, glibc [12], whose maintainer steadfastly refuses to include these improved APIs, labelling them “horribly inefficient BSD crap” [4], despite prior evidence that they are faster is most cases than the APIs they replace [13]. As a result, over 100 of the software packages present in the OpenBSD ports tree maintain their own strlcpy and/or strlcat replacements or equivalent APIs - not an ideal state of affairs.
它在 libbsd 库中可用于 Linux:
在 Debian 和 Ubuntu 以及其他发行版中有软件包:
即使您不想依赖 glibc 以外的任何东西,也可以很容易地将其添加到您的项目中,因为整个源代码很短,并且在许可下可用:
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
来源:http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/string/strlcpy.c?rev=1.11
关于c++ - strncpy 复制超过指定大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27330913/
我敢肯定以下这个问题已经被问了很多,但顺便问一下,因为我还没有找到答案。 我必须重新创建函数 strncpy(我不需要/不想要任何解决方案)并且我无法重现此函数的确切行为。 这是我的代码: int m
我对 strncpy 功能感到非常沮丧。我做了这样的事情: char *md5S; //which has been assign with values, its length is 44 char
我一直无法让这部分代码正常工作。我试图获取一个要复制的字符数组,这样我就可以计算出有多少 token 可以动态分配并保存它们以供检查环境变量。但是,当它尝试对原始字符串进行 strncpy 时,我一直
编辑:变量名 我正在制作一个链表,当我尝试释放一个节点时,它给了我一个错误。我跟踪我的代码,发现当我使用这段代码创建节点时,我的错误就根深蒂固了。 奇怪的是,如果我分配的字符比我想要的少一个,它就可以
当我在我的机器上运行一些代码时,它会按照我的预期运行。 当我在同事身上运行它时,它表现不佳。这就是发生的事情。 我有一个字符串,其值为: croc_data_0001.idx 当我对长度为 18 的字
基本上,我的程序使用链表向机器人发出命令。我正在使用 strcpy() 将命令复制到我的链表节点结构中,但它在末尾添加了不需要的字符(即“right”变成了“右\000-°\rd")。我使用过 str
我编写了一个程序来查找最长的单词并打印它。 我的代码是: #include #include #include int MaxWord(char text[],char[]); int main
如果我对字符串 cat 和 dog 使用 strncpy 函数。我不明白\0字符是否被计算在内,所以我想知道最终结果是否是catdo?还是类似于 cat\0do strncpy("猫", "狗", 2
我想做的是要求用户输入以下格式的内容:cd 目录。然后我将“cd”存储在一个字符串中,将“directory”存储在另一个字符串中。这是我的代码: void main() { char buf[
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
我正在为一个项目使用 C 样式字符串,但我自己有点困惑。我正在检查字符串以查看它们的前缀是什么(zone_、player_ 等),然后获取字符串的其余部分。 else if(strncmp(info,
我刚开始使用 C++,所以我可能在这里犯了一个愚蠢的错误。下面是我的代码以及注释中的输出。我正在使用 Xcode。 #include #include using namespace std;
我正在审查函数 strncpy 的字符串操作函数。我有 7 个输出而不是 3 个,谁能解释一下?非常感谢。 char x[] = "just see that."; char y[15
#include using namespace std #include int main(){ char token[] = "some random string"; cha
我最近遇到了一些遗留代码,并注意到有时(并非总是)以下代码片段需要很长时间才能执行。 #define NUM_OF_RECORDS 100000 char* pzBuffer = new char[N
我正在探索关于 strncpy 的 C,因为大多数人说它比 strcpy 更安全(附加参数,长度,以避免缓冲区溢出)。我还想找出非空终止字符串对程序的影响。这是我拥有的代码片段。 char passw
我想在 C 中模拟一个向下增长的调用堆栈并将以下内容压入堆栈: 这是我写的测试代码,我只尝试压入字符串,字对齐,然后将地址压入刚刚压入的字符串: #include #include #includ
我是 c 的新手,想将字符串分成两部分。这是我的代码: #include #include #include void test(char** a, char** b) { const ch
我需要通过添加“_out”和更改扩展名来修改通过参数传递的文件名。所以,首先,我复制没有扩展名的旧文件的名称,就像那样 char* arg1 = argv[1]; char* var1 = N
我正在逐行读取文件,其中每一行的格式为: “数字 1\t 数字 2”。 我正在使用 strtok 和 strncpy 拆分然后根据需要存储这两个值。但是,我发现在 strncpy 之后,number1
我是一名优秀的程序员,十分优秀!