Read in file as string and store into struct variables

Hello, I am in a basic programming class, and we have a lab that I am pretty stuck on. The instructions are:
"The object of this program is to rearrange the data in two input files into two output file that have the same names. The input version of the files will contain a mixture of male and female names, the program rearranges the contents of the two files so that all of the female names are in one of the data files and all of the male names are in the other file. You should define a struct for the data and read in the data from both filesinto dynamically allocated arrays of the struct.

The program will also report the total number of female names and males names found in each of the input files to the display before the program ends. Your output to the display should look like the following example:

Example Output

datafile1.txt contained x female names and y male names
datafile2.txt contained y female names and y males name
where x and y are of course the actual counts of the names in the files.

The difficulty here is that yoou will be using the same file for input and output (but not at the same time). To use the same files You will need to first open the files for input and close then after reading in all of the data. When finished reading in the data close the input file stream. Then you will need to open the same files for output. Since we need to look at all of the input data in order to count the totakl number of each genfer we need to read both input files into memory so we can then close the files and reopen them as output files. Each of the input files contain the total number of entries in the file in the first line of the file. Each line of data will contain a name consisting of a first name and a last name seperated by a space than after another space there will be a gender indicator of either "F" or "M".

EXAMPLE INPUT datafile1.txt

4
Dana Smith F
River Jones M
Jordan Pollic F
Liska Fanta M
EXAMPLE INPUT datafile2.txt

5
Ray Harper F
Morgan McMillan F
Jessie James M
Reese Moore M
Taylor Kale F

The number of data entries that is contained in the first line of each file will give you the information you need to allocate enough dynamic memory to read the entire file into memory. You will output all of the female names into the file datafile1.txt and all of the male names into the file datafile2.txt. The first line of each output file will need to contain the total number of names followed by a space and then a text string indicating the gender of the names in the that output file.

EXAMPLE OUTPUT datafile1.txt

5 female
Dana Smith
Jordan Polick
Ray Harper
Morgan McMillan
Taylor Kale
EXAMPLE OUTPUT datafile2.txt

4 male
River Jones
Liska Fanta
Jessie James
Reese Moore"


My main problem is reading in the file and sorting it into the struct variables. I know what I have on line 43 is wrong, but it gets across what I want to do I think. My other problem is actually sort the two files, I know how to output into stream files, but I don't know where to start with this.

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 <string>

struct dataFileInfo {
    std::string firstName;
    std::string lastName;
    char gender;
    };
    
bool readRecord(std::ifstream &, dataFileInfo &);
void (std::ostream &, );

int main()  {
    dataFileInfo record;
    
    std::ifstream myFile;
    myFile.open("datafile1.txt");
    if(!myFile)   {
        std::cout << "Sorry, bad file.";
        exit(0);
    }
    readRecord(myFile, record);
    myFile.close("datafile1.txt");
    
    
    myFile.open("datafile2.txt");
    if(!myFile) {
        std::cout << "Sorry, bad file.";
        exit(0);
        }
    readRecord(myFile, record);
    myFile.close("datafile2.txt");
    
    std::ostream myFile;
    myFile.open("datafile1.txt");
    
    
}

bool readRecord(std::ifstream &myFile, dataFileInfo &record)  {
    std::string incomingData;
    int numOfNames = incomingData.at(0);
    for(int i = 0; i < numOfNames; i++) {
        // SORT INTO STRUCTURE VARIABLES
        }
    
    
    }
    
void (std::ostream &myFile, )    {
    
    }
Last edited on
You seem to be very confused as to whether you are reading ONE person or many (line 41ff) and I have no idea what you were intending to do with your (unnamed) other function.

You also do not seem to have considered your strategy; call it pseudocode if you wish. I don't think you actually need to "sort" data; you simply write your collection of people to one file of the other according as their gender is M or F.

I would suggest that you keep each person's data in a struct called ... Person:
1
2
3
4
5
6
struct Person
{
   string firstName;
   string lastName;
   char gender;
};

and collect ALL data into a vector of Persons, called ... people
vector<Person> people;


Your pseudocode might look something like this:
(1) read datafile1.txt, pushing back each person into your container people, incrementing int variables male or female according to gender;
(2) output the male/female counts for that file
(3) read datafile2.txt, pushing back each person into the SAME container, incrementing variables male or female according to gender;
(4) output the male/female counts for that file (either start these again from scratch, or subtract off stored values from the first file)
(5) loop through the people collection and output to the first data file only if their gender is F;
(6) loop through the people collection and output to the second data file only if their gender is M.
To what extent - if any - you break this down into separate functions is up to you.


Your file reads/writes would be simplified by defining stream extraction(>>) and insertion(<<) operators; e.g.
1
2
istream &operator >>( istream &strm, Person &p ) { return strm >> p.firstName >> p.lastName >> p.gender; }
ostream &operator <<( ostream &strm, const Person &p ) { return strm << p.firstName << " " << p.lastName; }

Then you can write, e.g.
1
2
3
         Person p;
         fstrm >> p;
         people.push_back( p );

and
if ( p.gender == 'M' ) fstrm << p << '\n';


You will need to use open() and close() carefully if you are using the same filenames for input and output. If you decide to use the same fstream (but you don't need to) then you will also need to open it with parameters ios::in or ios::out as appropriate.


It goes without saying that you should tackle the problem INCREMENTALLY, testing each part for compilation and then for sensible action as you go. You are not doing that at present.


BTW, I've just noticed that this new thread is exactly the same topic as your previous and very recent thread. DON'T DO THAT: it spreads confusion. In future, bump your thread up (once) if you would like it to get more attention.
Last edited on
Topic archived. No new replies allowed.