0

So I'm having trouble storing the information after parsing a text-file. The text file has something like this inside it

1234 Main St; Oakland; CA; USA
2134 1st St; San Fransico; CA; USA
etc. etc.

I currently have these variables that I'm going to use to store the address's information

vector <string> addressInfo;
vector <string> street;
vector <string> city;
vector <string> state;
vector <string> country;

I'm also currently able to get the program to remove the ";" from the file and store all the information into a single vector using getline

while(read == true)
{
    getline(in, line, ';');
    if (in.fail())
    {
        read = false;
    }
    else
    {
        addressInfo.push_back(line);
    }
}

When I do a for-loop to output what is inside the addressInfo vector, I get

1234 Main St
Oakland
CA
USA
etc. etc.

I know that I might have to use stringstream but I don't know how to store each line from the vector into the different variables.

SVINT
  • 3
  • 1

3 Answers3

0

I don't think you should store your data like this:

vector <string> addressInfo;
vector <string> street;
vector <string> city;
vector <string> state;
vector <string> country;

I think it should look like this:

struct address_info {
  std::string street;
  std::string city;
  std::string state;
  std::string country;
  address_info() {}

  // from C++11, I prefer below style
  //address_info() = default;
  address_info(std::string street_, std::string city_, std::string state_, std::string country_)
    : street(street_), city(city_), state(state_), country(country_)
  {}
};
int main()
{
   std::vector<address_info> list;
   // Let's assume that you know how to get this
   std::string line = "1234 Main St; Oakland; CA; USA";
   std::string street;
   std::string city;
   std::string state;
   std::string country;
   std::istringstream iss(line);
   // remember to trim the string, I don't put it here
   getline(iss, street, ';');
   getline(iss, city, ';');
   getline(iss, state, ';');
   getline(iss, country, ';');

   // This is the C++11 code to add to vector
   //list.emplace_back(street, city, state, country);

   // Pre-C++11 style
   list.push_back(address_info(street, city, state, country));
}

Anyway, you can go search for a csv library.

Danh
  • 5,916
  • 7
  • 30
  • 45
0

Here is a c++14 version using tokenized algorithm (pretty similar to STL style). It's c++14 only because I am using a generic lambda but can be easily made c++11 compatible as well.

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>

template <typename Iter, typename Executor>
void for_each_token(Iter first, Iter last, 
                    Iter dfirst, Iter dlast,
                    Executor ex)
{
  if (first == last) return;
  auto tmp = first;
  while (first != last) {
    first = std::find_first_of(first, last, dfirst, dlast);
    ex(tmp, first);
    if (first == last) break;
    first++;
    tmp = first;
  }
  return;
}

template <typename Executor>
void for_each_token_str(const std::string& str, const std::string& delims, Executor ex)
{
  for_each_token(std::begin(str), std::end(str), std::begin(delims), std::end(delims), ex);
}

int main() {
  std::ifstream in("parse.txt");
  if (not in) return 1;

  std::string line;
  std::vector<std::string> tokens;

  std::vector <std::string> addressInfo;
  std::vector <std::string> city;
  std::vector <std::string> state;
  std::vector <std::string> country;

  while (std::getline(in, line)) {
    for_each_token_str(line, ";", [&](auto f, auto l) {
          tokens.emplace_back(f, l);
        });

    int idx = 0;
    addressInfo.emplace_back(tokens[idx++]);
    city.emplace_back(tokens[idx++]);
    state.emplace_back(tokens[idx++]);
    country.emplace_back(tokens[idx++]);

    tokens.clear();
  }

  auto print = [](std::vector<std::string>& v) {
    for (auto & e : v) std::cout << e << ' ';
    std::cout << std::endl;
  };

  print(addressInfo);
  print(city);
  print(state);
  print(country);

  return 0;
}

I am assuming that you are using a vector for every field following SOA (Struct of arrays) principle. If not, I would rather have them grouped in a structure.

NOTE: I have skipped some error checking which you should not.

Arunmu
  • 6,837
  • 1
  • 24
  • 46
0

Push_back the names/string in the respective vector. newline is a default delimiter for getline.

string street_name;
string city_name;
string state_name;
string country_name;

while(getline(cin, street_name, ';') && getline(cin, city_name, ';') && 
      getline(cin, state_name, ';') && getline(cin, country_name))
{
    street.push_back(street_name);
    city.push_back(city_name);
    state.push_back(state_name);
    country.push_back(country_name);    
}
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79