0

这是一个有点奇怪的问题。

我写了一个 C 函数。它的'喜欢' strchr / strrchr。它应该在 c 字符串中查找一个字符,但要向后查找,并返回一个指向它的指针。由于 c 字符串不是“null 启动”,它还需要第三个参数“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:  Pointer to character where to start going back.
* begin: Pointer to characther where search will end.
*
* Returns NULL if c is not between [begin,from]
* Otherwise, returns pointer to c.
*/
char* b_strchr(const char* begin,int c,const char* from){


    while (begin<=from){

        if (*from==c) return from;
        from--;
     }
     return NULL;
}
4

4 回答 4

5

编辑更好,但界面仍然令人惊讶。我将begin参数(正在搜索的干草堆)作为第一个参数,将c参数(正在搜索的from)放在第二个参数,将参数(搜索的开始位置)放在第三个参数。在相当大的 API 集合中,该顺序似乎是惯用的。

于 2009-07-03T02:42:43.390 回答
2

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

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

于 2009-07-03T01:49:02.290 回答
1

如果 begin 是 from,则当前代码将始终返回 begin,这不是您想要的。循环之后的代码可以只返回NULL。而不是 begin != from 在循环条件中,我会使用 begin < from 否则当有人混淆参数的顺序时,你将指针算术溢出。

编辑:重新考虑,因为你想要 [begin, from] 包含它应该是 begin <= from

于 2009-07-03T02:58:23.040 回答
1

我写了一个 C 函数。它的'喜欢' strchr / strrchr。

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

你看到它有什么缺陷吗?

是的。一些。:-(

由于b_strchr()can return NULL,您不应该将其直接放入printf()语句中。延迟NULL通常会导致段错误。

您最喜欢的变体可能会更好...

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().

于 2009-07-03T03:27:16.917 回答