我发现很难相信我是遇到这个问题的第一个人,但是搜索了很长时间并没有找到解决方案.
我想使用strncpy但是它具有UTF8意识,因此它不会将utf8字符部分写入目标字符串.
否则,您永远无法确定结果字符串是否为有效的UTF8,即使您知道源是(当源字符串大于最大长度时).
验证生成的字符串可以工作,但如果要调用它,最好有一个strncpy函数来检查它.
glib有,g_utf8_strncpy但这会复制一定数量的unicode字符,而我正在寻找一个限制字节长度的复制函数.
要清楚,通过"utf8 aware",我的意思是它不应超过目标缓冲区的限制,并且它绝不能只复制utf-8字符的一部分.(给定有效的utf-8输入必须永远不会导致utf-8输出无效).
一些回复指出,strncpy所有字节都为空,并且它不会确保零终止,回想起来我应该要求知道utf8 strlcpy,但当时我不知道这个函数是否存在.
我只是乱搞strncpy.
我的程序看起来像这样
typedef struct
{
char from_str[10];
}test;
main ()
{
test s1;
memset(&s1,0,sizeof(test));
char src[10]="himansh";
char dest[10];
memset(dest,0,10);
src[3]='\0';
printf("src is %s and strlen is %d \n",
src,strlen(src));
fflush(stdout);
strncpy(s1.from_str,src,100);
printf("s1.from_str is %s , src is %s \n",
s1.from_str,src);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
在我执行strncpy之前,我在"src"字符串中添加了一个"\ 0"字符,"src"字符串的长度变为3,目标数组的大小为10.但是在strncpy中我将要复制的字节数复制为100 .
这意味着我的源字符串以NULL结尾.现在strncpy像任何字符串函数应该尝试只复制3个字节,即使我提供的字节数大于3(在这种情况下为100).它做到了,但我也得到了分段错误.
我的结果如下所示
src is him and strlen is 3
s1.from_str is him , src is him
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)
为什么这个分段错误发生在这里.
有人可以帮我从这里出去吗.
是否有一个确切相当于strncpy()函数的C++标准库中?我的意思是一个函数,它将一个字符串从一个缓冲区复制到另一个缓冲区,直到它到达终止0?例如,当我必须从不安全的源解析字符串时,例如TCP数据包,所以我能够在处理数据时执行长度检查.
我已经搜索了很多关于这个主题的内容,我也发现了一些有趣的话题,但所有这些人都对std :: string :: assign感到满意,它也可以将一个字符大小复制为参数.我对这个函数的问题是,它不会执行任何检查,如果已经命中了终止空值 - 它需要给定的大小严重并且像memcpy一样复制数据到字符串的缓冲区中.这样,如果在应对时有这样的检查,则分配和复制的内存比必须完成的内存多得多.
这就是我目前正在解决这个问题的方式,但是我希望避免一些开销:
// Get RVA of export name
const ExportDirectory_t *pED = (const ExportDirectory_t*)rva2ptr(exportRVA);
sSRA nameSra = rva2sra(pED->Name);
// Copy it into my buffer
char *szExportName = new char[nameSra.numBytesToSectionsEnd];
strncpy(szExportName,
nameSra.pSection->pRawData->constPtr<char>(nameSra.offset),
nameSra.numBytesToSectionsEnd);
szExportName[nameSra.numBytesToSectionsEnd - 1] = 0;
m_exportName = szExportName;
delete [] szExportName;
Run Code Online (Sandbox Code Playgroud)
这段代码是我的PE-binaries解析器的一部分(准确地解析导出表的例程).rva2sra将相对虚拟地址转换为PE节相对地址.该ExportDirectory_t结构包含RVA二进制,其中出口名称应该是零结尾的字符串.但事情并非总是如此 - 如果有人想要它,它将能够省略终止零,这将使我的程序运行到不属于该部分的内存中,它最终会崩溃(在最好的情况下...).
我自己实现这样的功能不是一个大问题,但如果在C++标准库中实现了这个解决方案,我更喜欢它.
海湾合作委员会8增加了-Wstringop-truncation警告.来自https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82944:
在GCC 8.0中通过r254630为bug 81117添加的-Wstringop-truncation警告专门用于突出显示strncpy函数的非预期用途,该函数截断源字符串中的终止NUL字符.请求中给出的此类滥用的示例如下:
char buf[2];
void test (const char* str)
{
strncpy (buf, str, strlen (str));
}
Run Code Online (Sandbox Code Playgroud)
我用这段代码得到了同样的警告.
strncpy(this->name, name, 32);
warning: 'char* strncpy(char*, const char*, size_t)' specified bound 32 equals destination size [-Wstringop-truncation`]
Run Code Online (Sandbox Code Playgroud)
考虑到this->name是char name[32]和name是一个char*具有长度可能比32更大我想复制name成this->name和截断它,如果它是大于32更大的应该size_t是31而不是32?我糊涂了.this->nameNUL终止并不是强制性的.
我正在使用下面的代码
char call[64] = {'\0'} /* clean buffer */
strncpy(call, info.called, sizeof(call));
Run Code Online (Sandbox Code Playgroud)
我总是使用sizeof作为目的地来保护溢出,incase源大于目标.这样我就可以防止缓冲区溢出,因为它只会复制目标可以处理的内容.
但我现在想知道它是否会终止目的地.
几个案例.
1)如果来源更大.我能做到这一点:
call[strlen(call) - 1] = '\0'; /* insert a null at the last element.*/
Run Code Online (Sandbox Code Playgroud)
2)如果源小于目的地.call是64个字节,我复制了50个字节,因为它是源的大小.它会自动将null放在51元素中吗?
非常感谢任何信息,
关于以下内容strncpy:http://www.cplusplus.com/reference/clibrary/cstring/strncpy/,它提到了以下内容:
没有空字符隐式附加到目标的末尾,因此如果源中的C字符串的长度小于num,则目标将仅以空值终止.
这句话是什么意思?
你怎么会得到一个字符串的最后一个字,从'\ 0'换行符到最右边的空格?例如,我可以在这样的地方为str分配一个字符串:
char str[80];
str = "my cat is yellow";
Run Code Online (Sandbox Code Playgroud)
我怎么会变黄?
我正在尝试理解string.h函数.这是我自己的strncpy()实现
char * my_strncpy(char *dst, const char* src, int n)
{
char *orig = dst;
const char *hold = src;
int count = 0, remain = 0;
while(*(hold++))
count++;
if ( n > count )
{
remain = n - count;
n = count;
}
while(n--)
*dst++ = *src++;
while(remain--)
*dst++ = '\0';
return orig;
}
Run Code Online (Sandbox Code Playgroud)
但是在看这里的 glibc实现时,我想知道为什么它太大而复杂.
我使用" time "命令测试了执行时间.两个功能几乎相同.
有人可以分享关于glibc strncpy()的知识以及我在my_strncpy()中缺少的知识.
该函数strncpy()并不总是null终止所以我想知道什么是总是null终止的最佳替代?我想要一个函数,如果:
strlen(src) >= n /*n is the number of characters to be copied from source*/
Run Code Online (Sandbox Code Playgroud)
没有必要像这样添加更多代码:
buf[sizeof(buf)-1] = 0;
Run Code Online (Sandbox Code Playgroud) 我使用下面的代码:
char filename[ 255 ];
strncpy( filename, getenv( "HOME" ), 235 );
strncat( filename, "/.config/stationlist.xml", 255 );
Run Code Online (Sandbox Code Playgroud)
收到此消息:
(warning) Dangerous usage of strncat - 3rd parameter is the maximum number of characters to append.
(error) Dangerous usage of 'filename' (strncpy doesn't always null-terminate it).
Run Code Online (Sandbox Code Playgroud)