2015-10-22 107 views
-2
#include<stdio.h> 
#include<string.h> 

void* lsearch(void* key,void* base,int size,int elemSize){ 
    int i = 0; 
    for(i = 0; i < size; i++){ 
    void* elemAddr = ((char*)base + (i * elemSize)); 
    if(memcmp(key,elemAddr,elemSize)==0){ 
      return elemAddr; 
    } 
    } 
    return NULL; 
} 

int main(){ 
    char* a[] = {"Hello","Good","Morning","Ladies"}; 
    int size = sizeof(a)/sizeof(a[0]); 
    char* key = "Good"; 
    char* search = (char*)lsearch(&key,&a,size,sizeof(char*)); 
    if(search == NULL){ 
    printf("\n key value not found!! \n"); 
    return -1; 
    } 
    printf("\n search : %s \n",search); 
    return 0; 
} 

OUTPUT:垃圾值

search : �@ 

我試圖做琴絃一個lsearch在一個數組...匹配字符串,但我得到打印的垃圾值。爲什麼會這樣..

+2

1)不要用C投'無效*'! 2)不要在你定義類型的地方使用'void *',除非你恨編譯器或者更喜歡調試代碼,因爲類型錯誤編譯器可以很容易地報告! – Olaf

+0

我繼續說:不要在'void *'上做算術運算,這個沒有明確定義。你的搜索函數調用是僞造的,它有太多的'&'運算符 –

+2

甚至更​​多的問題:'lsearch'假設數組的每個元素大小相等,但'a'中的字符串不是。此外:'lsearch'比較指向字符串的指針,而不是字符串本身。 – Kninnug

回答

3

修正:

有幾件事情是錯誤的,這裏有最顯着的問題:在void*

  • 算術:非法,
  • 一個some_type array[] = {...};的長度sizeof(array)(沒有花哨的部門),
  • 不恰當的選擇接口:當你剛剛閱讀時,考慮使用const參數。另外,確保參數的類型與您的參數一致(例如baseconst char* []而不是char*)。最後,要查找字符串數組中的鍵,您需要一個鍵,數組的句柄和數組的長度,就這些了。

Run It Online

#include<stdio.h> 
#include<string.h> 

const char* lsearch(const char* key, const char* base[], const size_t size){ 
    size_t i = 0; 
    const size_t max_len = strlen(key); // strlen(), that's how you compute the length of a string (you might add `+1` to include `\0` if you want) 

    for(i = 0; i < size; i++){ 
    const char* elemAddr = base[i]; // Arithmetic on a void* is illegal in both C and C++: https://stackoverflow.com/a/3524270/865719 
    if(memcmp(key, elemAddr, max_len)==0) { // @TODO use strncmp(), more appropriate, and safer. In particular, if strlen(elemAddr) < strlen(key) 
      return elemAddr; 
    } 
    } 
    return NULL; 
} 

int main() { 
    // init 
    const char* a[] = {"Hello","Good","Morning","Ladies"}; 
    const size_t size = sizeof(a); // size of the array -- i.e. element count 

    // search 
    const char* key = "Morning"; 
    const char* search = lsearch(key, a, size); 

    // results 
    if(search == NULL) { 
    printf("\n key value not found!! \n"); 
    return -1; 
    } 

    printf("\n search : %s \n",search); 
    return 0; 
} 

正如指出的Jongware,更好的辦法是使用字符串比較功能。在我看來,最安全的辦法是

int strncmp(const char *s1, const char *s2, size_t n); 

而且你會用它作爲這樣的:

// safer. in particular, if (and when) strlen(elemAddr) < strlen(key) 
if(strncmp(key, elemAddr, max_len) == 0) { 
     return elemAddr; 
} 
+2

你確定你沒有在這裏比較地址嗎?一個適當的字符串比較應該使用'strcmp'。正確完成,它需要'int(* compareFunction)(void *,void *)'compareXX'回調' – usr2564301

+0

我同意:)剛剛編輯答案提及'strncmp()',這應該足夠了這樣一個簡單的例子。 – 865719

0

這將做到這一點:

printf("\n search : %s \n",*(char**)search); 

你試圖從右側位置讀取,但是編譯器沒有千牛流如何訪問它

+1

這是一個在C中使用野生指針拍攝大象的典型例子。只是鑄造不是如何解決它,但獲得的類型是正確的,而不是在任何地方都使用'vloid *'。難怪這會搞砸.. – Olaf

+0

這不是很好,我同意,但這是一個修復。我假設這裏指針指向的地方沒有錯誤(在這個特定的代碼中指針是正確的) – CIsForCookies

+1

'search'已經是一個類型。如果這與'lsearch'返回的不一樣,那麼這個函數有問題,或者'search'的類型必須被修正。但不僅僅是向'printf'投下一個參數。這是維護的噩夢。就像畫一艘溺水的潛艇一樣。 – Olaf