2009-07-03 19 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()

相關問題