extract line of text into a variable string

Viewed 104

I'm building a code that must search for a line of text in a string variable that contains many lines of text (example the text variable has lines formed like this MILAN;F205).

Once the user has entered the city he wants to search for, the program must search the database for the city entered by the user (in this case Milan) and extract only that line so in this case it extracts MILAN;F205 and puts it in the variable result.

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <algorithm>

using namespace std;
string file_content();


int main()
{
    string database = file_content();
    string result,city;
    int len_database = database.size();
    
    cout<<"which city do you want to look for? ";
    cin>>city;
    //cerchiamo la città nel database

    if (database.find(city) != string::npos) 
    {
        //cout<<"the code is present in the database"
        //how should i continue?
    }else{
        cout << "it is not present in the database! ";
        return 0;
    }

    cout << result;
    return 0;
}


string file_content()
{
    // filestream variables 
    fstream file;
    string filename;

    // we declare filename which corresponds to the file we want to open
    filename = "lista-codici.txt";

    //open the file
    file.open(filename.c_str());

    // create a stringstream
    stringstream buffer;

    //passes the file buffer to the stringstream
    buffer << file.rdbuf();

    //reading the file
    return buffer.str();
}

How do I extract a specific line of text present in the database variable?

1 Answers

You could:

  • read your input stream into a vector of lines, and
  • walk that vector of lines checking if it starts with a given city name;
  • copying those lines that do match to an output vector (or just printing them out, or whatever).

The example below:

  • uses a std::istringstream instead of a std::fstream as input, and
  • takes the walk of the input lines and the creation of the output vector to a filter_by_city function.

[Demo]

#include <algorithm>  // copy_if
#include <iostream>  // cout
#include <iterator>  // istream_iterator
#include <sstream>  // istringstream
#include <string>
#include <string_view>
#include <vector>

auto filter_by_city(const std::vector<std::string>& lines, std::string_view city) {
    std::vector<std::string> ret{};
    std::copy_if(std::cbegin(lines), std::cend(lines), std::back_inserter(ret),
        [&city](const auto& line) {
            return line.substr(0, line.find(';')) == city;
    });
    return ret;
}

int main()
{
    std::istringstream iss{"MILAN;F205\nROME;G306\nMILAN;H407\nFIRENZE;I508\n"};
    std::vector<std::string> lines{std::istream_iterator<std::string>{iss}, {}};
    for (auto&& line : filter_by_city(lines, "MILAN")) {
        std::cout << line << "\n";
    }
}

// Outputs:
//
//   MILAN;F205
//   MILAN;H407

A probably better option, considering your input file is a database, would be to:

  • read your input stream into a map of cities, and
  • query for a specific city.

[Demo]

#include <algorithm>  // transform
#include <iostream>  // cout
#include <iterator>  // istream_iterator
#include <map>
#include <sstream>  // istringstream
#include <string>
#include <utility>  // make_pair

auto create_db(std::istringstream& iss) {
    std::map<std::string, std::string> ret{};
    std::transform(std::istream_iterator<std::string>{iss}, {},
        std::inserter(ret, std::end(ret)),
        [](const auto& line) {
            auto sep{ line.find(';') };
            return std::make_pair(line.substr(0, sep), line.substr(sep + 1));
    });
    return ret;
}

int main()
{
    std::istringstream iss{"MILAN;F205\nROME;G306\nNAPOLI;H407\nFIRENZE;I508\n"};
    auto db{ create_db(iss) };
    if (db.contains("MILAN")) {
        std::cout << "MILAN: " << db["MILAN"] << "\n";
    }
}

// Outputs:
//
//   MILAN: F205
Related