是否有安全版的strlen?

BЈо*_*вић 26 c c++ string

std :: strlen不处理不是\ 0终止的c字符串.它有安全版吗?

PS我知道在c ++中应该使用std :: string而不是c字符串,但在这种情况下,我的字符串存储在共享内存中.

编辑

好的,我需要补充一些解释.

我的应用程序从共享内存(有一定长度)获取一个字符串,因此它可以表示为一个字符数组.如果库中有一个错误写入此字符串,则该字符串不会被终止,并且strlen可能会失败.

MSa*_*ers 15

您已添加该字符串在共享内存中.这保证可读性和固定大小.因此,你可以使用size_t MaxPossibleSize = startOfSharedMemory + sizeOfSharedMemory - input; strnlen(input, MaxPossibleSize)(注意额外nstrnlen).

MaxPossibleSize如果\0共享内存中没有,则返回,如果有,则返回input字符串长度.(当然MaxPossibleSize-1,最大可能的字符串长度是在共享内存的最后一个字节是第一个的情况下\0)


小智 12

非空终止的C字符串不是C字符串,它们只是字符数组,并且无法找到它们的长度.

  • @unapersson:假设用户在"安全"这个词的"非正统"含义中表示"安全",这个词由"strlcpy"等"安全"字符串函数使用,你说的不是真的.嗯,这是真的,但不相关,因为提问者没有问如何找到没有nul终结符的东西的"长度",他询问如何找到长度,如果它有一个,如果没有则不会崩溃.有人可能知道缓冲区长度,但不知道它是否包含一个空字节,而**可以找出哪个和(如果它是一个字符串)长度. (8认同)
  • 好的,但有一个替代std :: strlen是安全的吗? (2认同)
  • 用户?提问者,我的意思是.`strlcpy`是一个BSD函数,我用它作为我曾经*人们在C语言中讨论"安全"字符串函数时所知道的唯一一种事情的例子 - 这需要一定长度并避免在那边工作. (2认同)

Den*_*nis 9

如果将c-string定义为

char* cowSays = "moo";
Run Code Online (Sandbox Code Playgroud)

然后你自动地在末尾获得'\ 0'并strlen返回3.如果你定义如下:

char iDoThis[1024] = {0};
Run Code Online (Sandbox Code Playgroud)

你得到一个空的缓冲区(和字符数组,所有这些都是空字符).只要不超过缓冲区长度,就可以用你喜欢的东西填充它.在开始时strlen将返回0,一旦你写了一些东西,你也会得到正确的数字strlen.
你也可以这样做:

char uhoh[100];
int len = strlen(uhoh);
Run Code Online (Sandbox Code Playgroud)

但那会很糟糕,因为你不知道那个数组中有什么.它可能会击中你可能没有的空字符.关键是null字符是声明字符串完成的已定义标准方式.
没有空字符意味着根据定义字符串未完成.改变这将打破字符串如何工作的范例.你想要做的是制定自己的规则.C++会让你这样做,但你必须自己编写很多代码.

编辑 从新添加的信息中,您要做的是循环遍历数组并手动检查空字符.如果您只期望ASCII字符,也应该进行一些验证(特别是如果您需要字母数字字符).这假设您知道最大尺寸.如果您不需要验证字符串的内容,那么您可以使用以下strnlen函数系列之一:http: //msdn.microsoft.com/en-us/library/z50ty2zh%28v=vs.80%29.aspx
http://linux.about.com/library/cmd/blcmdl3_strnlen.htm

  • @VJo:因为`strnlen`不是标准的C或C++,你可能更喜欢`memchr`(检查null和指针减法).或者你可能不介意'strnlen`在Windows和Posix中. (7认同)
  • 谢谢.我在寻找strnlen (4认同)

Ser*_*gei 8

是的,从 C11 开始:

size_t strnlen_s( const char *str, size_t strsz );

位于<string.h>


And*_*ips 6

size_t safe_strlen(const char *str, size_t max_len)
{
    const char * end = (const char *)memchr(str, '\0', max_len);
    if (end == NULL)
        return max_len;
    else
        return end - str;
}
Run Code Online (Sandbox Code Playgroud)