0

So I declared this structure data:

struct Auxiliary
        {
          char come_greet[100], leave_greet[100], aux_words[100];  
        };
        Auxiliary j[1000];

And now I need to use this data in a function but I can t pass the structure as a parameter:

void search_for_val_name(struct StructName & y[] ,char name1[],char answer[], int mm)
    {
        for(int i=0;i<mm;i++)
            {
                if(strchr(answer,(*y).name1))
                    return (*y).name1;
            }
    }

How can I make this function work properly?

2
  • Does this answer your question? C++ pass an array by reference Commented Feb 24, 2021 at 0:41
  • Since you're writing C++, I doubt very much that your use of naked char arrays is desired. For all I know, you're just preemptively creating buffer overflows. Why do you use fixed-size char arrays instead of std::string, and why do you not use std::vector<Auxiliary>? Commented Feb 24, 2021 at 2:05

2 Answers 2

1

First of all, this is C++, so all those fixed-size arrays are just a buffer overflow in waiting - with structures so large, there's no performance benefit from doing it that way.

Thus, I'd start as follows. Whenever an unknown number of characters is desired, std::string is used. Whenever an unknown number of elements of some other type is desired, std::vector is used.

#include <string>
#include <vector>

struct Auxiliary {
    std::string come_greet, leave_greet;
    std::vector<std::string> aux_words; // if this is just one word, don't call it words!

    bool operator==(const Auxiliary &o) const {
        return &o == this ||
            o.come_greet == come_greet &&
            o.leave_greet == leave_greet &&
            o.aux_words == aux_words;
    }
};

struct Outer {
    static Auxiliary not_found;

    std::vector<Auxiliary> j; // j is a terrible name - choose something with meaning!

    Auxiliary &find_answer(std::string Auxiliary::*field, const std::string &answer);
};

Then, the search is a method: it doesn't need to have the mm argument since it knows the size of the j vector, it doesn't need to be fed j since it has direct access to it, and we can actually write C++, not C. The field argument specifies which member of the Auxiliary structure is meant to be searched, e.g. &Auxiliary::come_greet. Also note the use of std::string::find instead of strstr. find_answer returns a reference to an Auxiliary, since returning references is cheap. It could also return a value (i.e. Auxiliary, not Auxiliary&), but that would copy the value, most likely unnecessarily.

Auxiliary Outer::not_found;

Auxiliary& Outer::find_answer(std::string Auxiliary::*field, const std::string &answer) {
  for (auto &aux : j)
    if ((aux.*field).find(answer) != std::string::npos)
      return aux;
  return not_found;
}

If you wouldn't need to modify Auxiliary via the returned reference, the returned type should be const Auxiliary&.

Finally, a little test that demonstrates the behavior:

#include <cassert>

int main() {
    Outer outer;
    outer.j = {
                {"come0", "leave0", {"auxa_0", "auxb_0"}},
                {"come1", "leave1", {"auxa_1"}}
            };
    assert(outer.find_answer(&Auxiliary::come_greet, "foo") == Outer::not_found);
    assert(outer.find_answer(&Auxiliary::come_greet, "come0") == outer.j[0]);
    assert(outer.find_answer(&Auxiliary::come_greet, "come1") == outer.j[1]);
    assert(outer.find_answer(&Auxiliary::leave_greet, "leave0") == outer.j[0]);
    assert(outer.find_answer(&Auxiliary::leave_greet, "leave1") == outer.j[1]);
}

This concludes the complete compileable example.

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

Comments

0

Since the number of array elements to search is variable, you should pass the structure array by pointer, not by reference.

It also looks like you want the caller to specify which struct field to search in the array. You can use a pointer-to-member to do that.

Try this:

typedef char wordStr[100];

struct Auxiliary
{
    wordStr come_greet, leave_greet, aux_words;
};

char* search_for_val_name(Auxiliary* y, wordStr Auxiliary::*field, char* answer, int mm)
{
    for(int i = 0; i < mm; ++i)
    {
        if (strstr(answer, y[i].*field))
            return y[i].*field;
    }
    return NULL;
}
Auxiliary j[1000];
...
char *found = search_for_val_name(j, &Auxiliary::aux_words, "answer", 1000);
...

Comments

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.