Readinf from a file and storing in multiple data type variables.

I am writing a program that creates an address book from a text file. I have to store some things in strings and some in enums. I think I have a handle on the enums, but certain things like the street address is giving me a hard time since it consists of several words and must be saved in one string variable. Also any numeric values should be stored as a string like the zip code. Relation is and
enum everything else a string.

here is an example of an entry on the text file
Bill Blanco 322-765-1788 6 30 1981 FRIEND 1667 N. Virginia Ave. Los Angeles CA 90029

Here is the code in question, any help would be appreciated.
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
  enum relationShipType { FAMILY, FRIEND, BUSINESS, OTHER };

void addressBookType::readFromFile()
{
	string fileName;

	string firstName, lastName, streetAdress, city, state, zip, phoneNum;
	int dobMonth, dobDay, dobYear;
	relationShipType relation;

	cout << "Please enter the file to read from:" << endl;
	cin >> fileName;
	ifstream inputFile;
	inputFile.open(fileName);
	if (inputFile)
	{
		while (inputFile >> firstName >> lastName >> phoneNum >> dobMonth >> dobDay >> dobYear >> relation >> streetAdress >> city >> state >> zip)
		{
			inputFile >> firstName >> lastName >> phoneNum >> dobMonth >> dobDay >> dobYear >> relation >> streetAdress >> city >> state >> zip;
		}

		cout << firstName << " " << lastName << " " << phoneNum << " "   << dobMonth << " " << dobDay << " " << dobYear << " " << relation << " " << streetAdress << " " << city << " " << state << " " << zip;
	}
}

std::istream& operator >> (std::istream& i, relationShipType& relation)
{
	relation = FAMILY;
	std::string value;
	if (i >> value) {
		if (value == "FRIEND") {
			relation = FRIEND;
		}
		else if (value == "BUSINESS") {
			relation = BUSINESS;
		}
		else if (value == "OTHER") {
			relation = OTHER;
		}
	}
	return i;
}
Do you have a choice on the file format, or is it something which is given to you ready-made?

If you have the option, I would suggest the use of a delimiter (I like to use the tab character '\t') to separate individual fields, definitely there is a need for something to identify the streetAdress and city.

Also, in real-world data, some information may be missing, we may for example have just a first name and a phone number, or have full details but no date of birth etc. It depends what situations you need to handle.
the text file is not given and for the purpose of this assignment all fields are provided accordingly. I will look into a delimiter, thanks for the suggestion.
Having looked at this a bit more, I'm not quite sure what classes and types your program will be using. For the time being I've considered it as just using the local variables defined inside the function. Let's say we have an input file like this:
Bill	Blanco	322-765-1788	6 30 1981	FRIEND	1667 N. Virginia Ave.	Los Angeles	CA	90029

for clarity, I'll mark where the tab characters are with a '#' character, but this isn't the real file
Bill#Blanco#322-765-1788#6 30 1981#FRIEND#1667 N. Virginia Ave.#Los Angeles#CA#90029


You could read that file like 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
void readFromFile()
{
    std::string fileName;

    std::cout << "Please enter the file to read from:" << std::endl;
    std::cin >> fileName;
    std::ifstream inputFile;
    inputFile.open(fileName);
    if (!inputFile)
    {
        std::cout << "Could not open input file: " << fileName << '\n';
        return;    
    }
    
    std::string firstName;
    std::string lastName;
    std::string streetAdress;
    std::string city;
    std::string state;
    std::string zip;
    std::string phoneNum;
    int dobMonth = 0;
    int dobDay   = 0;
    int dobYear  = 0;
    relationShipType relation = OTHER;
        
    
    std::string line;
    const char  tab = '\t';
    while (getline(inputFile, line)) 
    {
        //std::cout << "Line:" << line << '\n';
        std::istringstream ss(line);
        
        getline(ss, firstName, tab);
        getline(ss, lastName, tab);
        getline(ss, phoneNum, tab);
        ss >> dobMonth >> dobDay >> dobYear >> relation; ss.ignore(1000, tab);
        getline(ss, streetAdress, tab);
        getline(ss, city, tab);
        getline(ss, state, tab);
        getline(ss, zip);

        if (ss)
        {
            std::cout << firstName << " " << lastName << " " << phoneNum << " "   
                      << dobMonth << " " << dobDay << " " << dobYear << " " << relation << " " 
                      << streetAdress << " " << city << " " << state << " " << zip << '\n';
        }
    }
    
}

As an extra level of safety, you could also read the dob as a string using getline just like the other variables, and then if you like, use another stringstream to parse the integers within that dob string. When I say safety, I mean if for some reason the dob was invalid, as a string it would be ok, but as a set of integers, the input could fail.
Last edited on
Topic archived. No new replies allowed.