2015-10-07 155 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