1

lets say that we have:

string list[]= {"12.34.56.78","55.34.5","23.44.5"}

I want the user to enter part of the string which is also a string: for example string 55 and it will loop through the string a and look for the whole string and print "55.34.5" What I was doing is:

str is a string input and list is a whole list of the strings

for (int i=0; i<n; i++){
  for (int j=0; j<(list[i].length()); j++){
    for (int k=0; k<(str.length()); k++){
      if (list[i][j] == str[k])
        cout<<list[i]<<endl;
      else
        break;

however, there is a problem with this, and it doesn't work properly.

Update:

so I have updated my code to:

for (int i=0; i<n; i++)
    if (strncmp(list[i].c_str(), str.c_str(), str.length()) == 0)){
      cout<<list[i]<<endl;
      }

however, this doesn't output any of the strings.

5
  • 2
    Think at a higher level... you have a string class look at the member functions of this class and see if one provides what you need. Commented Sep 25, 2012 at 2:13
  • 1
    What if the user enters "34"? Do you want the first two strings to match ("12.34.56.78" and "55.34.5")? In other words, are you looking for the user string to be a substring of a string in your list? Commented Sep 25, 2012 at 2:20
  • output both choices then Commented Sep 25, 2012 at 2:45
  • Wait, if your string is "abcdef", and the user enters "cde", is that a match, or does it have to match from the beginning? Commented Sep 25, 2012 at 3:06
  • basically like it is stated in the problem, that between dots have to be match in strings Commented Sep 25, 2012 at 3:54

3 Answers 3

2

For any function fanatics (see it work):

std::string findInList(const std::vector<std::string> &searchFrom, const std::string &lookFor) {
    for (const std::string &s : searchFrom) {
        if (s.find(lookFor) != std::string::npos)
            return s;
    }

    return "";
}

I used a vector instead of an array because vectors are better and don't require extra work to get the array size from. If C++11 isn't being used, a normal for loop works perfectly fine.

This also assumes you want the first match to be returned. A probably better option is to return a vector of strings, empty if none are found, which makes it explicit that none were found, or as many as are found otherwise. Instead of returning the found string, just add it to the vector and continue on, returning the vector when you're done.

If you want to model the standard algorithms, you can also have it take a beginning iterator and an ending iterator instead of the actual container. This will allow you to call it on any type of container, including arrays, with any range in that container to look through.

Taking both points into consideration, you can evolve it into this (see it work):

template <typename Iterator>
std::vector<std::string> findInList(Iterator start, const Iterator end, const std::string &lookFor) {
   std::vector<std::string> ret;

   for (; start != end; ++start)
       if (start->find(lookFor) != std::string::npos)
           ret.emplace_back(*start);

   return ret;
}

Again, if not using C++11, emplace_back can be swapped out for push_back.

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

5 Comments

I actually don't want to use vectors, because this is just part of my program so it would change the rest of it
It shouldn't be hard to substitute arrays for vectors here. The idea is there.
somehow this looks complicated to me, I like the idea of the codes that Marc Cohen used, but somehow its not working for me
@MW, My first sample is almost like Marc's. The difference is that Marc's compares the whole of one string to that many beginning characters of the other, whereas std::string::find returns the position of where, if anywhere, the substring is found in the bigger one. If it isn't found, find returns npos. The for loop is just a bit condensed to save space, but a normal one with iterators or indices from 0 to < searchFrom.size() works just as well. The vectors can be swapped for arrays pretty easily, but if you keep the function, you'll need to know the size. The second is idiomatic.
@MW, The only thing missing from the first was that you need all of the strings, in which case, you can combine the second's use of ret with the first's loop, emplace_back/push_backing s to the vector instead of returning it, and replacing the "not found" return with the vector, which is nicely empty if nothing is found.
2

That just compares the first character in list[i] with the first char in your string. If the corresponding first chars match, it prints the entire ith string and then advances k, the offset into your str, without changing the offset into the string against which you're comparing. I think you can dispense with the inner two loops, and use a fixed length string comparison, i.e.,

for (int i=0; i < n; i++) {
  if (strncmp(list[i].c_str(), str.c_str(), str.length()) == 0) {
    // match
  }
}

4 Comments

how would you match it then though?
Good point, I need to compare the response from strncmp to zero - edit above.
it doesn't give me anything actually
strncmp will not find a substring unless they match from the start, use the find member function of std::string like chris showed in his answer.
0

Here's an answer that combines both of the previous answers. It uses the find member function of the std::string class

for (int i=0; i < n; i++) {
    if (list[i].find(str) != std::string::npos) {
        std::cout << list[i] << std::endl;
    }
}

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.