0

Working on a project where I need to read from a txt file where every three lines has us state information needed, where I have to parse the info into my class I created. I Know I need a couple for loops, but not sure how to format the code.

This is the format if the txt file:

New Hampshire
Concord
9304 1788 9
Massachusetts
Boston
8257 1788 6
Vermont
Montpelier
9609 1791 14

Every third line includes three seperate ints needed to be parsed. Here's my code so far:

int main()
{

    ifstream file("Example_State_data.txt");
    string name;
    string capital;
    int area = NULL;
    int index = NULL;
    int addYear = NULL;
    int addOrder = NULL;

    hashFunc States;
    States.setStateInfo("Hawaii", "Honlulu", 0, 0, 0);
    States.printTable();

    if (file.is_open())
    {
        while (!file.eof())
        {
            file >> name;
            index++;

        }
        cout << index << " items found";
        file.close();
    }
    else
    {
        cout << "file is not open!";
    }
}

void hashFunc::setStateInfo(string name, string capital, int area, int 
admissionYear, int admissionOrder)
{
    int index = Hash(name);
    if (hashTable[index]->name == "empty")
    {
        hashTable[index]->name = name;
        hashTable[index]->capital = capital;
        hashTable[index]->area = area;
        hashTable[index]->admissionYear = admissionYear;
        hashTable[index]->admissionOrder = admissionOrder;
    }
  • That's not a class struct. That's just a bunch of variables. Also don't assign `NULL` to an `int`. Presumably you mean those numbers to be initialized `0`. – tadman Apr 26 '17 at 23:00
  • 1
    Which class you want to populate from the text file and also you need to show code for `States`. – SomeDude Apr 26 '17 at 23:05
  • Pat, what you're looking to do is called serialization. Check out this [related SO question](https://stackoverflow.com/questions/234724/is-it-possible-to-serialize-and-deserialize-a-class-in-c). – 0X1A Apr 26 '17 at 23:06
  • @svasa will do. tadman got it – Pat J Louis Apr 26 '17 at 23:06
  • Recommended reading [Why is iostream::eof inside a loop condition considered wrong?](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – user4581301 Apr 26 '17 at 23:17
  • 1
    @tadman, NULL **is** 0. Look it up. It does look **bad** to us people and the designer of C++ would say don't use macros but as far as the compiler is concerned, the compiler never sees _NULL_. – user34660 Apr 27 '17 at 01:45
  • @0X1A, I don't see class information being read in; just data. Therefore it is just reading data, much as has been done for more than half a century. – user34660 Apr 27 '17 at 01:49
  • That is not parsing. Everything is in fixed, predictable locations. Please don't call it parsing, just as it is not serialization. Also, I don't understand the relevance of the hashTable and that stuff; I see that Robert does not do anything with that; is the hashing unnecessary? I might have an alternative to Robert's but if the hashing is important then that should be explained. For production code, I would be more conservative and attempt to catch possible problems with the data. – user34660 Apr 27 '17 at 01:58
  • 1
    @user34660 I know what it is, but it's intended for use as a pointer. This usage is completely absurd. – tadman Apr 27 '17 at 02:05
  • 1
    @tadman, then say that; just don't imply it is not being set to zero. – user34660 Apr 27 '17 at 02:15

1 Answers1

0

If you just need a way to read data and place it in a struct, here's a example that would read your data:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main()
{
    ifstream inFile("Example_State_data.txt");
    if(!inFile.good()) { cout << "File read error" << '\n'; exit(1); }

    struct data
    {
        string name;
        string capital;
        int area;
        int addYear;
        int addOrder;
    };

    vector<data> all_data;

    data one;

    while
    (
        getline(inFile, one.name)
        &&
        getline(inFile, one.capital)
        &&
        inFile
            >> one.area
            >> one.addYear
            >> one.addOrder
    )
    {
        all_data.push_back(one);
        getline(inFile, one.name); // pass third line
    }


    // ---- Read back ---------
    size_t n = all_data.size();
    for(size_t i = 0; i < n; ++i)
    {
        cout
            << all_data[i].name << '\t'
            << all_data[i].capital << '\t'
            << all_data[i].area << '\t'
            << all_data[i].addYear << '\t'
            << all_data[i].addOrder << '\n';
    }
    // --------------------------------------

}
Robert C. Holland
  • 1,283
  • 13
  • 42
  • Very helpful, but the items aren't being put into the hashtable? The struct is already defined in the header file: class hashFunc { private: static const int HTSize = SIZE; struct stateData { string name; string capital; int area; int admissionYear; int admissionOrder; stateData* next; }; stateData* hashTable[HTSize]; – Pat J Louis Apr 27 '17 at 02:03
  • Just add, `States.setStateInfo(one.name, one.capital, one.area, one.addYear, one.addOrder);` in the while loop replacing `all_data.push_back(one);` -- if I understood how your custom hash function is structured. – Robert C. Holland Apr 27 '17 at 02:15