2015-10-07 154 views
0

我想找到一個字符串,它是在二維字符數組中並返回它的索引。例如:查找C字符串中的二維字符數組中的字符串

char idTable[255][32]; 
char tester[] = { 't','e','s','t','e','r','\0' }; 
memcpy(idTable[43], tester, 7); 

uint8_t id = getID(name[0]); 
//name is returned from function "char **name = func();" 
//but I have the same results when I try using normal char array... 

我已經與下面的代碼的第一部分部分成功,但它是找到一個匹配,如果單詞的一部分是相同的(一個,ONETWO)。如果我將「else if」添加到第一個「if」,它總是會轉到「else if」。

文件打印不同的結果爲 printf("idTable string lenght:\t %u\n", strlen(idTable[index]));printf("foundMatch string lenght:\t %u\n", strlen(foundMatch)); 剩下的,除非我添加printf("Index:\t %i\n", index);

uint8_t getID(char *name) { 
    printf("\nInserted name:\t %s\n", name); 
    uint8_t index; 

    for (uint8_t r = 0; r < 255; r++) { 
    if (strstr(idTable[r], name) != NULL) { 
     printf("Found '%s' in position:\t %d\n", name, r); 
     index = r; 
    } 
    } 


    printf("Index:\t %i\n", index); // THIS LINE 

    char foundMatch[strlen(idTable[index])]; 
    printf("idTable string lenght:\t %u\n", strlen(idTable[index])); 

    for (uint8_t c=0; c<strlen(idTable[index]); c++) { 
     foundMatch[c] = idTable[index][c]; 
    } 
    printf("foundMatch string lenght:\t %u\n", strlen(foundMatch)); 

    if (strcmp(foundMatch, nodeName) == 0) { 
     printf("Confirmed\n"); 
     return index; 
    } else { 
     printf("Second test failed\n"); 
     return 0; 
    } 
} 

爲什麼我得到這個奇怪的結果,有沒有更好的方法來做到這一點?

+0

提醒:'printf'和'strlen'功能需要一個「\ 0 '來標記C風格字符串的結尾。你有沒有把一個放在字符串的末尾?這些函數將繼續執行直到找到'\ 0'。 –

+0

函數參數'* name'應該是空終止的,因爲我使用'strtok'來寫入包含它的數組。我添加了'\ 0'到'tester []'數組,但輸出保持不變'nodeIDsTable string lenght:6','foundMatch string lenght:14' –

回答

-1

您需要IDTABLE行中複製後,到一個NUL添加到foundMatch數組末尾:

foundMatch[strlen(idTable[index])] = '\0'; 

的「foundMatch串lenght」前右(長度)消息。

strlen是一個昂貴的函數,每次都會使用字符串。您應該調用一次,將其存儲在局部變量中,然後引用該變量,而不是反覆調用strlen

+0

你根本不應該使用'strlen',而我們'對此。 –

+0

謝謝,不知怎的,這解決了這個問題。我不知道爲什麼在初始化'tester []'時添加'\ 0'不能解決它,但稍後添加它可以修復它,但它可以工作。 –

1

我不知道你是如何初始化你的idTable條目的,但是如果你使用的是你在問題開始時顯示的方法,你將會遇到問題。你不能假設idTable保留的所有空間都被初始化爲0,所以idTable [43]不是以空字符結尾的字符串。因此,idTable [43]不需要等於空字符串「tester」。

您的getID函數不會返回任何東西,儘管它的簽名。所以它甚至不會按原樣編譯。

+0

我將'\ 0'添加到'tester []',但我的輸出相同。它編譯和工作正常,如果我添加'printf(「索引:\ t%i \ n」,索引);'在代碼中間。 –

+0

我認爲您運行的代碼必須與您發佈的代碼不同。在您發佈的代碼中,'index'變量不在'// THIS LINE'行的作用域(未定義)中,因此這可能無法工作。 –

+0

實際代碼較長,但我發佈的部分幾乎相同。我收到編譯器發出的警告:'index'可能未被初始化(如果沒有匹配),但是它在'getID()'函數的開始處定義。感謝您指出,我會在最終決定時解決它。 –

1

下面是實際的C++的解決方案,而不是C.

std::array<std::string, 255> idTable; 
idTable.at(43) = "tester"; 

std::pair<std::size_t, std::size_t> findInIdTable(std::string const& what) { 
    for (unsigned i = 0; i < idTable.size(); ++i) { 
     std::size_t pos = idTable.at(i).find(what); 
     if (pos != std::string::npos) { 
      return std::make_pair(i, pos); 
     } 
    } 
    // if the code reaches this place, it means "not found". Choose how you want to deal with it 
    // my personal suggestion would be to return std::optional<std::pair<...> instead. 
} 

如果你要放棄pos值,很容易改變。

Live On Coliru

+0

感謝您的回答,但我無法讀取C++。對於標題中的混淆,很抱歉。 –

+1

@VasilKalchev如果你不能閱讀C++,我們應該如何回答?你應該如何理解解決方案或編寫自己的解決方案? –

+0

我在我的問題中使用C代碼,但是我在問題的標題中犯了一個錯誤。 –

1

在類別:使用C++

當然,使用std::array<char, 32>std::string如果可能的話。我堅持你的選擇了這個答案:

Live On Coliru

#include <algorithm> 
#include <iostream> 
#include <cstring> 

char idTable[255][32] = { }; 

int main() { 
    using namespace std; 
    // initialize an entry 
    copy_n("tester", 7, idTable[43]); 

    // find match 
    auto match = [](const char* a) { return strcmp(a, "tester") == 0; }; 
    auto index = find_if(begin(idTable), end(idTable), match) - idTable; 

    // print result 
    cout << "match at: " << index; 
} 

打印

match at: 43