M W
M W

Reputation: 67

c++ finding a string using part of the string

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.

Upvotes: 1

Views: 178

Answers (3)

amdn
amdn

Reputation: 11582

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

Upvotes: 0

Marc Cohen
Marc Cohen

Reputation: 3808

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

Upvotes: 2

Qaz
Qaz

Reputation: 61970

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.

Upvotes: 2

Related Questions