Sep 27, 2022 at 7:48am Sep 27, 2022 at 7:48am UTC
You might want to use std::istringstream from the <sstream> header. Then you can read from the line the same way you can with std::cin, std::ifstream, etc.
1 2 3 4
std::istringstream iss(line);
std::getline(iss, city, ':' );
std::getline(iss, restaurant);
...
You might also have to come up with a way to "trim" whitespaces from the ends of the strings because "Oakland " will not compare equal to "Oakland".
Last edited on Sep 27, 2022 at 7:56am Sep 27, 2022 at 7:56am UTC
Sep 27, 2022 at 8:03am Sep 27, 2022 at 8:03am UTC
What are you trying to do? Do you try to find multiple locations? Since you never break the loop?
This is one approach to find the city and return the restaurant:
1 2 3 4 5 6 7 8 9 10 11 12 13
while (getline(read,output))
{
const std::size_t pos = output.find(":" );
if (pos != std::string::npos)
{
const std::size_t pos_city = output.find(word, 0, pos);
if (pos_city != std::string::npos)
{
scope = output.substr(pos + 1);
break ;
}
}
}
Not tested!
If you want the line number you might try this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
int i = 0;
for (; getline(read,output)); ++i)
{
const std::size_t pos = output.find(":" );
if (pos != std::string::npos)
{
const std::size_t pos_city = output.find(word, 0, pos);
if (pos_city != std::string::npos)
{
scope = output.substr(pos + 1);
break ;
}
}
}
Last edited on Sep 27, 2022 at 8:10am Sep 27, 2022 at 8:10am UTC
Sep 27, 2022 at 12:25pm Sep 27, 2022 at 12:25pm UTC
If you want to do this by reading from a file and checking, then perhaps something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <string_view>
#include <optional>
#include <cctype>
std::string lc(std::string s) {
for (auto & c : s)
c = static_cast <char >(std::tolower(static_cast <unsigned char >(c)));
return s;
}
std::string_view trim(std::string_view sv) {
while (std::isspace(static_cast <unsigned char >(sv.back())))
sv.remove_suffix(1);
while (std::isspace(static_cast <unsigned char >(sv.front())))
sv.remove_prefix(1);
return sv;
}
std::optional<std::string> findRest(std::istream& read, std::string_view word) {
const auto w { lc(std::string(trim(word))) };
read.clear();
read.seekg(0);
for (std::string line; std::getline(read, line); ) {
std::istringstream iss(line);
std::string city, rest;
std::getline(iss, city, ':' );
std::getline(iss, rest);
if (lc(std::string(trim(city))) == w)
return std::string(trim(rest));
}
return {};
}
int main() {
const std::string file { "city.txt" };
if (std::ifstream read { file })
for (std::string word; std::getline(std::cin, word); )
if (auto res { findRest(read, word) }; res)
std::cout << word << " - " << *res << '\n' ;
else
std::cout << word << " not found\n" ;
else
std::cout << "Cannot open file\n" ;
}
However, in cases like this it's more usual to first read the file into a container and then search the container. Consider:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <string_view>
#include <optional>
#include <unordered_map>
#include <cctype>
using Data = std::unordered_map<std::string, std::string>;
std::string lc(std::string s) {
for (auto & c : s)
c = static_cast <char >(std::tolower(static_cast <unsigned char >(c)));
return s;
}
std::string_view trim(std::string_view sv) {
while (std::isspace(static_cast <unsigned char >(sv.back())))
sv.remove_suffix(1);
while (std::isspace(static_cast <unsigned char >(sv.front())))
sv.remove_prefix(1);
return sv;
}
Data read(const std::string& fn) {
Data data;
if (std::ifstream read { fn })
for (std::string line; std::getline(read, line); ) {
std::istringstream iss(line);
std::string city, rest;
std::getline(iss, city, ':' );
std::getline(iss, rest);
data[lc(std::string(trim(city)))] = std::string(trim(rest));
}
return data;
}
int main() {
const std::string file { "city.txt" };
const auto data { read(file) };
if (!data.empty())
for (std::string word; std::getline(std::cin, word); )
if (const auto res { data.find(lc(std::string(trim(word)))) }; res != data.end())
std::cout << word << " - " << res->second << '\n' ;
else
std::cout << word << " not found\n" ;
else
std::cout << "Cannot open file\n" ;
}
Last edited on Sep 27, 2022 at 12:26pm Sep 27, 2022 at 12:26pm UTC
Sep 28, 2022 at 1:47am Sep 28, 2022 at 1:47am UTC
Sounds great, thank you for all your helps guys this has helped me a lot.