C 这个功能是否更安全?寻找提示和你的想法!

C 这个功能是否更安全?寻找提示和你的想法!,c,unsafe,C,Unsafe,这是一个有点奇怪的问题 我写了一个C函数。它“像”strchr/strrchr。它应该在c字符串中查找一个字符,但要向后查找,并返回指向该字符的指针。由于c字符串不是“null initiated”,因此它还接受第三个参数“count”,表示它应该向后查看的字符数 /* *s: Position from where to start looking for the desired character. *c: Character to look for. *count: Amount of t

这是一个有点奇怪的问题

我写了一个C函数。它“像”strchr/strrchr。它应该在c字符串中查找一个字符,但要向后查找,并返回指向该字符的指针。由于c字符串不是“null initiated”,因此它还接受第三个参数“count”,表示它应该向后查看的字符数

/*
*s: Position from where to start looking for the desired character.
*c: Character to look for.
*count: Amount of tests to be done
*
* Returns NULL if c is not in (s-count,s)
* Returns a pointer to the occurrence of c in s.
*/
char* b_strchr(const char* s,int c,size_t count){

    while (count-->0){

        if (*s==c) return s;
        s--;
     }
     return NULL;
}
我已经做了一些测试,但是 你看到它有什么缺点吗?安全问题?有什么改进吗?是否可以改进? 更重要的是:这是个坏主意吗

一些用法

    char* string = "1234567890";

    printf("c: %c\n",*b_strchr(string+9,'5',10));//prints 5

    printf("c: %c\n",*b_strchr(string+6,'1',7));//prints 1
编辑:新界面,一些更改。
/*
*from:指向开始返回的字符的指针。
*开始:指向搜索将结束的字符的指针。
*
*如果c不在[begin,from]之间,则返回NULL
*否则,返回指向c的指针。
*/
char*b_strchr(常量char*begin,int c,常量char*from){

while(begin代码有一个深奥的接口-传入一个指向字符串最后一个字符和字符串长度的指针。这将导致使用它时出现问题


(或者,代码有一个bug-您应该在循环之前向s添加count。)

编辑更好,但界面仍然令人惊讶。我将
开始
参数(正在搜索的草堆)作为第一个参数,
c
参数
(正在搜索的针)秒,以及
from
参数(搜索的开始位置)第三,在相当大的一组API中,这种顺序似乎是惯用的。

如果begin是from,则当前代码将始终返回begin,这不是您想要的。循环后的代码可以返回NULL。我将使用begin 编辑:再考虑一下,因为您希望[begin,from]具有包容性,所以它应该是begin 我写了一个C函数,它“像”strchr/strrchr

您试图重新发明
strrchr()
,所以它不像
strchr()

你看到它有什么缺点吗

是的,有几个-(

由于
b_strchr()
可以返回
NULL
,因此不应将其直接放入
printf()
语句中。延迟
NULL
通常会导致segfault

你可能会更好地与你最喜欢的变化

char *result;

result = b_strchr(string + 9, 'a', 10));
if (result == NULL)
{
    printf("c: NULL\n");
}
else
{
    printf("c: %c\n", *result);
}
还有,什么时候

(count >= length of the input string) and the character is not found
您将得到不可预测的结果,因为
s
不再指向字符串中的字符-
s
指向字符串开头之前的内存。例如,请尝试

result = b_strchr(string + 9, 'a', 11));
if (result == NULL)
{
    printf("c: NULL\n");
}
else
{
    printf("c: %c\n", *result);
}
看看会发生什么

扩展您的用例,以包括您知道将成功工作的条件之外的条件。请其他人帮助您设计真正测试代码的测试用例

更重要的是:这是个坏主意吗

作为一种学习练习,绝对不是


但是,在这种情况下,对于生产代码,最好还是遵循标准
strrchr()

@Jonathan谢谢你的洞察力。你指的是什么bug?我的目的是s指向从哪里开始回望的字符。@Tom:如果界面符合你的预期,那么就没有bug。然而,大多数人,大多数时候,都会保留一个指向字符串开头的指针,有时(在这种情况下,必须)字符串的长度。这意味着人们将不得不进行您显示的加法运算。更传统的界面将使第一个参数指向字符串的开头;函数将进行加法运算。还要注意的是,令人不舒服的模式“s+9”和10、“s+6”和7。有人会犯错误的赌注是什么?@Jonathan,Thanks再次。我明白你的意思。更改了函数的界面,看到我的编辑,我认为现在好多了。谢谢!我没想过。我明白你的意思,但strrchr不是我需要的。我需要的是在我所在的较低地址中查找一个字符。至于printf测试,是的,你是对的。我故意在t情况下做了这些测试hat不会返回null,但感谢您的输入。请查看是否有更新版本。
result = b_strchr(string + 9, 'a', 11));
if (result == NULL)
{
    printf("c: NULL\n");
}
else
{
    printf("c: %c\n", *result);
}