2009-07-03 18 views
0

这是一个奇怪的问题。这个功能可以更安全吗?寻找提示和你的想法!

我写了一个C函数。它的'像'strchr/strrchr。它应该在c字符串中寻找一个字符,但是要倒退,并返回一个指向它的指针。由于c字符串不是“空启动的”,它还需要第三个参数“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; 
} 

回答

5

这与编辑好,但是界面依然令人惊讶。我把begin参数(草堆正在搜索)作为第一个参数,该参数c (在所搜索)第二,和from参数(开始搜索的位置)第三。这个顺序似乎在大量的API中是习惯用法的。

+0

谢谢!没有想过这件事。 – Tom 2009-07-03 02:48:59

2

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

(或者,代码有一个错误 - 你应该在循环之前增加计数秒)

+0

@Jonathan谢谢你的洞察力。你指什么错误?我的目标是指出角色从哪里开始回顾。 – Tom 2009-07-03 01:59:37

+1

@Tom:如果界面符合您的要求,那么就没有错误。然而,大多数人在大多数时间都保持一个指向字符串开头的指针,有时(在这种情况下)保持字符串的长度。这意味着人们将不得不做你添加的东西。一个更传统的接口将有第一个参数指向字符串的开始;该函数会添加。请注意,不舒服的模式的+ 9'和10,'+ 6'和7。什么是赌博的人会得到错误的? – 2009-07-03 02:12:15

+0

@Jonathan,再次感谢。我明白你的意思了。改变了功能的界面,看我的编辑,我觉得它现在好多了。 – Tom 2009-07-03 02:37:14

1

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

编辑:对,因为你想要第二个想法[开始,来自]包容性应该开始< =从

1

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

您试图重新创建strrchr(),所以它不像strchr()

您是否看到其中的缺陷?

是的。一些。 :-(

由于b_strchr()可以返回NULL,你不应该把它直接进入printf()声明。Deferencing 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 

你会得到unpredicable的结果,因为s不再指向一个字符— s是字符串开始前指向内存中的字符串中。举个例子,试试

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

看看会发生什么。

扩展您的使用测试用例,以包含您知道能够成功工作的条件。要求其他人帮助你设计能真正测试你的代码的测试用例。

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

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

但是,在这种情况下,对于生产代码,您最好坚持使用标准strrchr()

相关问题