首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >strnstr的一个简单而安全的实现(在char数组的前n个字符中搜索子字符串)

strnstr的一个简单而安全的实现(在char数组的前n个字符中搜索子字符串)
EN

Code Review用户
提问于 2016-06-20 12:29:20
回答 1查看 6.4K关注 0票数 4

我想建议以下实现:

代码语言:javascript
运行
复制
// Find an instance of substr in an array of characters
// the array of characters does not have to be null terminated
// the search is limited to the first n characters in the array.
char *strnstr(char *str, const char *substr, size_t n)
{
    char *p = str, *pEnd = str+n;
    size_t substr_len = strlen(substr);

    if(0 == substr_len)
        return str; // the empty string is contained everywhere.

    pEnd -= (substr_len - 1);
    for(;p < pEnd; ++p)
    {
        if(0 == strncmp(p, substr, substr_len))
            return p;
    }
    return NULL;
}

第一个参数的基本原理不是const,因为您可能希望使用返回值指针来修改该位置的数组。

为了完整性,在C++中,可以添加一个重载的变量,即const:

代码语言:javascript
运行
复制
const char *strnstr(const char *str, const char *substr, size_t n)
{
    return strnstr((char *)str, substr, n);
}

有什么评论吗?

正如建议的那样,下面是一个测试程序:

代码语言:javascript
运行
复制
#include <iostream>
#include <cstring>
#include <string>

int main()
{
    char s[] = "1234567890abcdefgh";
    size_t n = sizeof(s) - 1;

    const char *patterns[] = { "efgh", "0ab", "0b", NULL };
    const char *result = NULL;
    const char *pPattern = patterns[0];

    std::cout << "array of length " << n << " is: " << s << std::endl;

    for (int i = 0; pPattern; pPattern = patterns[++i])
    {
        result = strnstr(s, pPattern, n);
        std::cout << "finding " << pPattern << " n=" << n << ": "
            << (result ? result : "(null)") << std::endl;
    }

    pPattern = patterns[0];
    result = strnstr(s, pPattern, n-1);
    std::cout << "finding " << pPattern << " n=" << n-1 << ": "
        << (result ? result : "(null)") << std::endl;
    return 0;
}

输出:

代码语言:javascript
运行
复制
array of length 18 is: 1234567890abcdefgh
finding efgh n=18: efgh
finding 0ab n=18: 0abcdefgh
finding 0b n=18: (null)
finding efgh n=17: (null)
EN

回答 1

Code Review用户

回答已采纳

发布于 2016-06-20 23:25:05

  1. 设计:将str作为数组并搜索到n,与类似字符串的函数和strstr()不一致。与其“搜索仅限于数组中的前n个字符”,我还希望str中没有搜索空字符后面的字符。海事组织,一个设计缺陷。下面的评论假设str[i] == 0没有特殊的意义。
  2. 弱参数名strstr是数组的地址,可能不是字符串。调用潜在的非字符串str传递错误的想法。建议src等,在寻找子字符串时,我喜欢needlehaystack
  3. 由于C版本不更改str内容,建议使用const。“第一个参数的基本原理不是const,因为您可能希望使用返回值指针来修改该位置的数组。”不适用。将返回值强制转换为char *即可。跟随strstr()s轮胎。//自C图书馆。//预期签名:(为清晰起见) // C char *strnstr(const char *src,const char *substr,size_t n);// C++ char *strnstr( char *src,const char *substr,size_t n);const char *strnstr(const char *src,const char *substr,size_t n);
  4. 使用接近标准名称的名称是很棘手的。C保留带有某些前缀的名称,等等,*nix也是如此。可能使用CP_strnstr()和可选的#define strnstr CP_strnstr
  5. 角的情况:当strif(0 == substr_len) return str;一起返回时,size == 0没有意义。我想是NULL
  6. 有可能潜流。如果(n +1< needle ){返回NULL;} pEnd -= (substr_len -1),则haystack // add检查的长度可能更长或更短;

次要

  1. 在调试模式下,考虑对NULL char *strnstr(char *str,const *substr,size_t n) { assert(str =n == 0);
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/132519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档