0

I want to find a specific string in a list of sentence. Each sentence is a line delimited with a \n. When the newline is reached the current search should stop and start new on the next line.

My program is:

#include <iostream>
#include <string.h>
using namespace std;
int main(){
    string filename;
    string list = "hello.txt\n abc.txt\n check.txt\n"
    cin >> filename;
    // suppose i run programs 2 times and at 1st time i enter abc.txt
    // and at 2nd time i enter abc
    if(list.find(filename) != std::string::npos){
       //I want this condition to be true only when user enters complete
       // file name. This condition also becoming true even for 'abc' or 'ab' or even for 'a' also

        cout << file<< "exist in list";
    }
    else cout<< "file does not exist in list"
    return 0;
}

Is there any way around. i want to find only filenames in the list

jww
  • 97,681
  • 90
  • 411
  • 885
mahi.nawaz
  • 21
  • 2

2 Answers2

2

list.find will only find substring in the string list, but if you want to compare the whole string till you find the \n, you can tokenize the list and put in some vector.

For that, you can put the string list in std::istringstream and make a std::vector<std::string> out of it by using std::getline like:

std::istringstream ss(list);
std::vector<std::string> tokens;

std::string temp;
while (std::getline(ss, temp)){
    tokens.emplace_back(temp);
}

If there are leading or trailing spaces in the tokens, you can trim the tokens before adding them to the vector. For trimming, see What's the best way to trim std::string?, find a trimming solution from there that suits you.

And after that, you can use find from <algorithm> to check for complete string in that vector.

if (std::find(tokens.begin(), tokens.end(), filename) != tokens.end())
    std::cout << "found" << std::endl;
Community
  • 1
  • 1
Ahmad Khan
  • 2,655
  • 19
  • 25
1

First of all I wouldn't keep the list of files in a single string, but I would use any sort of list or vector. Then if keeping the list in a string is a necessity of yours (for some kind of reason in your application logic) I would separate the string in a vector, then cycle through the elements of the vector checking if the element is exactly the one searched. To split the elements I would do:

std::vector<std::string> split_string(const std::string& str,
                                  const std::string& delimiter)
{
    std::vector<std::string> strings;

    std::string::size_type pos = 0;
    std::string::size_type prev = 0;
    while ((pos = str.find(delimiter, prev)) != std::string::npos)
    {
        strings.push_back(str.substr(prev, pos - prev));
        prev = pos + 1;
    }

    // To get the last substring (or only, if delimiter is not found)
    strings.push_back(str.substr(prev));

    return strings;
}

You can see an example of the function working here

Then just use the function and change your code to:

#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
int main(){
string filename;
string list = "hello.txt\n abc.txt\n check.txt\n"
cin >> filename;

vector<string> fileList = split_string(list, "\n");
bool found = false;
for(int i = 0; i<fileList.size(); i++){
    if(fileList.at(i) == file){
        found = true;
    }
}
if(found){
    cout << file << "exist in list";
} else {
    cout << "file does not exist in list";
}
return 0;
}

Obviously you need to declare and implement the function split_string somewhere in your code. Possibly before main declaration.

Luca Angioloni
  • 2,243
  • 2
  • 19
  • 28