Input file format problem into array of structs

Pages: 12
So for my assignment there is a state population data file in this format for all 50 states (spaces included)

Idaho Boise 1,297,274
Washington Olympia 5,908,684
Vermont Montpelier 609,890
Hawaii Honolulu 1,216,642
Arizona Phonenix 5,140,683
Montana Helena 905,316
Virginia Richmond 7,100,702
North Dakota Bismarck 643,756
Colorado Denver 4,311,882
Mississippi Jackson 2,852,927
Delaware Dover 785,068

I need to store each state in an array of structs classified by state capital and population.
The instructor recommended I get each line using getline to store the entire file into a temporary array, then parse the array and copy each character into the appropriate piece of the array of structs.

I understand what I need to do but I cant implement it for some reason.
Could someone give me an example of what to do in this situation?
closed account (DSLq5Di1)
Post what you've got so far and we'll help nudge you in the right direction.
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
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;

struct state_info
{
char state ;
char capital ;
long population;
};
//prototypes
int ReadStateInfo();


int main()
{
   ReadStateInfo();
}

int ReadStateInfo()
{

  state_info array[50];
 ifstream infile("states.dat" );// reads in states from a text file
    if( !infile )
    {
        cerr << "Unable to open: \""  << endl;
        return  -1;
    }

    const int MAX_LINE = 128;
    char line[MAX_LINE];

    for (int i = 0; i<49; i++) //gets file line by line puts into temporary array
    {
        infile.getline(line,MAX_LINE);
        cout <<line[i];// outputs contents of array for testing(not working)
    }
int j;
for (int i = 0; i<20; i++) //coppies characters 5 thru 15 into state part of struct ommiting spaces
        {
        if (isalpha(line[i]))
        {
        line[i] = array[j].state;
        j++;
        }


        }

}
closed account (DSLq5Di1)
The first problem is your structure, a char will only store 1 character. I recommend changing the types of state and capital to string for simplicity.

state_info array[50]; This is more of a nitpick than an error, but.. array is a reserved keyword for C++/CLI, to avoid confusion it might be best to rename it. Using a vector here wouldnt go astray either.

A couple of changes to make life easier:-
1
2
3
4
5
6
7
8
9
10
11
12
13
    const int MAX_LINE = 128;
    char line[MAX_LINE];
    string line; // will resize when necessary to fit the length of any line

    for (int i = 0; i<49; i++) //gets file line by line puts into temporary array
    while (!infile.eof())
    {
        infile.getline(line,MAX_LINE);
        getline(infile, line);
        cout <<line[i];// outputs contents of array for testing(not working)
        cout << line << endl; // output test

        ...

I see a problem with your input as it is laid out now.. there is no delimiter between state and capital, how will you deal with multi-word places? "North Dakota Bismarck" for example.
Well how it was explained to me was that reading them in as strings directly from the file will cause it to go to the next part of the structure. So north would be saved as state, dakota would be saved as capital and bismark would be population.

The only way for me to do it would just be to read in each one in parsing the line array and copying them with the is digit and is char.
But doing it this way would make me use at least 50 loops just to read in the Data. I understand I can copy and past and change the intervals of i to where eavery single peice of data starts.
Is there an easier way to do this?
Do you have to use just spaces between words, etc in your data file?

If so, I see no way for you to deal neatly with both Little Rock, Arkansas and Charleston, West Virginia

Unless you do something horrible like special casing New, North, South, ...
Yes the data file is supposed to be left as is here is a link to the actual file
http://www2.cs.uidaho.edu/~bruceb/cs120/Assignments/states2000.dat
Something worth noting is that you know what the names of the states and their capitols are in advance. So for each line, you could use string::find to see if you have a match on the name and capitol of a state, and from that know how to fill your state_info structs.

-Albatross
closed account (DSLq5Di1)
Arkansas Little Rock
Massachusetts Boston
New Mexico Santa Fe
North Dakota Bismarck
Utah Salt Lake City

The point I'm trying to make is, how will you know which part of these words belong to your state and which to your capital? you can't, not without checking explicitly within your program. Such as,

1
2
3
4
5
6
7
8
9
10
11
12
// Crappy pseudo code
if (1st_word == "New" && 2nd_word == "Mexico")
{
    state = 1st_word + 2nd_word;
    capital = 3rd_word + 4th_word;
    population = parse_to_integer(remaining_part);
}
else if (1st_word == "Utah")
{
    state = 1st_word;
    capital = 2nd_word + 3rd_word + 4th_word
    ...

To avoid such ridiculous code you would need a delimiter other than whitespace seperating your state and capital..

Arkansas, Little Rock, 
Massachusetts, Boston, 
New Mexico, Santa Fe, 
North Dakota, Bismarck, 
Utah, Salt Lake City, 


-edit-
Tsk! I swear these forums are playing tricks on my eyes, I didnt see any of the posts above me, even after replying.

If your input is based on that file, you can definitely do what you were trying to do earlier based on their fixed positioning.
Last edited on
Yeah I think I've reasonably spent too much time on this assignment alone.
I'm going to go ahead and reformat the source file so it can be easily read in.
That's the only feasible solution I can see right now other than counting spaces and writing hundreds of lines of code.

Thanks for your help everyone I'll let you know if I run into more problems.
@sloppy 9
Do you know how to do what I was trying to do without 50+ seperate loops.
Its seems like way too much code for a simple task.
I've just looked at the data file your URL linked to.

And I see it's a fixed column width format, so that changes the ball game!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  State               Capital               Population      

     Idaho          Boise                      1,297,274
     Washington     Olympia                    5,908,684
     Vermont        Montpelier                   609,890
     Hawaii         Honolulu                   1,216,642
     Arizona        Phonenix                   5,140,683
     Montana        Helena                       905,316
     Virginia       Richmond                   7,100,702
     North Dakota   Bismarck                     643,756
     Colorado       Denver                     4,311,882
     Mississippi    Jackson                    2,852,927
     Delaware       Dover                        785,068
     Georgia        Atlanta                    8,206,975
     South Carolina Columbia                   4,025,061
     Illinois       Springfield               12,439,042
     Nebraska       Lincoln                    1,715,369

The title of your post now makes sense, by the way.

"Input file format problem into array of structs"

It is a trivial problem for this kind of format!
Alrighty, so I need to some how ignore the pre-set spaces and somehow ignore the commas in the population column then
Can somebody please give me a clue on how to do that?
Haha
Does "fixed column width" not represent a clue?
sure it gives me an idea of what to do some how skip over the fixed part when reading in
I'm just not sure how to do it
Last edited on
The instructions you posted look quite clear.

Have you done strings, or just arrays so far?

You must have done structs by now. And I assume a bit of string passing and file reading.

The wording does sound like you're expected to use a char buffer, but I haven't seen your notes.
Yeah we've gone over strings I remember him saying something about using a substring too. Havent ever used a char buffer
substr will solve the problem, with help from find (to find the end of the string)
Pages: 12