0

I am trying to find a string which is inside 2D char array and return it's index. For example:

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...

I've had partial success with the first part of the below code, but it is finding a match if a part of the word is the same (one, oneTwo). If I add "else if" to the first "if" it always goes to the "else if".

The rest of the file prints different results for printf("idTable string lenght:\t %u\n", strlen(idTable[index])); and printf("foundMatch string lenght:\t %u\n", strlen(foundMatch)); , unless I add 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;
  }
}

Why am I getting this strange results and is there a better way to do this?

2
  • Reminder: the printf and strlen functions require a '\0' to mark the end of a C-style string. Did you put one at the end of the string? These functions will keep executing until they find a '\0'. Commented Oct 7, 2015 at 3:18
  • The function parameter '*name' should be null terminated because I am using 'strtok' to write to the array containing it. I added '\0' to the 'tester[]' array, but the output stays the same 'nodeIDsTable string lenght: 6', 'foundMatch string lenght: 14' Commented Oct 7, 2015 at 3:38

4 Answers 4

1

I don't know how you are initializing your idTable entries, but if you are using the method that you showed at the start of the question you'll have problems. You can't assume all of the space reserved by idTable is initialed to 0's, so idTable[43] isn't a null terminated string. Therefore idTable[43] need not compare equal to the null terminated string "tester".

Also your getID function doesn't return anything despite its signature. So it won't even compile as-is.

Sign up to request clarification or add additional context in comments.

3 Comments

I added '\0' to 'tester[]', but I'm having the same output. It compiles and works fine if I add 'printf("Index:\t %i\n", index);' in the middle of the code.
I think that the code that you're running must be different than the code that you have posted. In the code that you have posted the 'index' variable is not in scope (not defined) at the '// THIS LINE' line so this cannot possibly work.
The actual code is longer, but the part I have posted is almost the same. I am getting a warning from the compiler that 'index' may not be initialized (if there is no match), but it is defined at the beginning of the 'getID()' function. Thank's for pointing it out though, I'll fix it when it is final.
1

Here's a solution in actual C++, not 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.
}

If you want to discard the pos value, it's easy to change as well.

Live On Coliru

4 Comments

Thanks you for your answer, but I can't read C++. Sorry for the confusion in the title.
@VasilKalchev if you can't read C++, how are we supposed to answer? How are you supposed to understand the solution or write your own?
I am using C code in my question but I made a mistake in the title of the question.
@VasilKalchev you can edit your posts, titles and tags.
1

In the category: Use C++

Of course, use std::array<char, 32> or std::string if possible. I stuck with your choices for this answer:

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;
}

Prints

match at: 43

Comments

-1

You need to add a nul to the end of the foundMatch array after copying in the idTable row:

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

right before the 'foundMatch string lenght' (length) message.

strlen is an expensive function that walks the string every time. You should call that once, store it in a local variable, then reference that variable rather than calling strlen repeatedly.

2 Comments

You shouldn't use strlen at all, while we're at it.
Thank you, somehow this fixed the problem. I don't know why adding the '\0' while initializing the 'tester[]' doesn't fix it, but adding it later fixes it, but it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.