Reading in the name "De Blasio" from text file?

I have to fill up an object array by reading from a file (called "customers"). Its working fine, except that one of the words I have to read if "De Blasio". It reads them as two separate names, but I want it to be read as a single name.

I tried using getline, but that doesn't seem to be working as there are other strings and integers within the file which Im also reading which dont have this problem.

Here is the relevant portion of my code below:

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
// declaring object
    cust customer[10];

    string first, last, state;
    double sales[2], totalSales;
    int units;

    for(int i=0; i<5; i++)
    {
        customers >> customer[i].first >> customer[i].last >> customer[i].state >> customer[i].sales[0]
        >> customer[i].sales[1] >> customer[i].sales[2] >> customer[i].units;
    }

printcust(customer, 5);

}

void printcust(cust customer[], int aSize)
{

for(int i=0; i<aSize; i++)
{
    cout << customer[i].first << "\t" << customer[i].last << "\t" << customer[i].state << "\t"
        << customer[i].sales[0] << " " << customer[i].sales[1] << " " << customer[i].sales[2]
        << "\t" << customer[i].units << endl;
}

return;
}



I call another function to print out the data. The output becomes nonsense after it prints "De Blasio".

Any help with this. How do I read the entire name "De Blasio" into a variable called "last" while also simultaneously reading in several other strings and integers from a file?
Last edited on
Here is what the text file looks like by the way:

Barack Obama DC 100 50 300 2000
Bill De Blasio NY 250 100 80 5000
Kirsten Gillibrand NY 50 100 200 1000
Chris Chrystie CT 100 200 300 5000
Loretta Lynch DC 50 80 200 1000


I have to read this and print it out in this same format.
It appears that your fields are tab separated (based on your output) so you can use getline() with the optional third parameter(a tab character) to retrieve the strings.

1
2
getline(customers, customer[i].last, '\t') >> customer[i].first >> customer[i].last >> customer[i].state >> customer[i].sales[0] 
>> customer[i].sales[1] >> customer[i].sales[2] >> customer[i].units;


^ im probably doing it wrong, but it didn't work.

How exactly do I do this?
Last edited on
Don't try to combine the getline() and extraction operator, and why are you trying to retrieve customer.last twice?

1
2
3
4
5
getline(customers, customer[i].first, '\t');
getline(customers, customer[i].last, '\t');
getline(customers, customer[i].state, '\t');
customers >> customer[i].sales[0] >> ..... etc ....;


You'll also need to do something about the end of line character before the end of the loop, to prevent problems.
Ah, I see. Thank you. Im a novice programmer so please excuse my stupidity.

I've removed the end of line at the end of the loop and it prints correct. I've also added a new loop within the original to calculate the totalSales (sum of three sales) of each customer.

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
 for(int i=0; i<5; i++)
    {
        getline(customers, customer[i].first, '\t');
        getline(customers, customer[i].last, '\t');
        getline(customers, customer[i].state, '\t');
        customers >> customer[i].sales[0] >> customer[i].sales[1] >> customer[i].sales[2] >> customer[i].units;
            for(int n=0; n<3; n++)
            {
                customer[i].totalSales+=customer[i].sales[n];
            }

    }

printcust(customer, 5);

cin.get();

}

void printcust(cust customer[], int aSize)
{

for(int i=0; i<aSize; i++)
{
    cout << customer[i].first << "\t" << customer[i].last << "\t" << customer[i].state << "\t"
        << customer[i].sales[0] << " " << customer[i].sales[1] << " " << customer[i].sales[2]
        << "\t" << customer[i].units << "\t" << customer[i].totalSales;
}

return;
}


However, the output is a bit strange. The customers[i].sales[2] variable for each variable comes out wrong, as welll as the totalSales. Why is this?

Also, how do I line up the chart in the output so its 8 neat columns?

Sorry for so many questions. Hoping someone can help me out with this.
Last edited on

However, the output is a bit strange. The customers[i].sales[2] variable for each variable comes out wrong, as welll as the totalSales. Why is this?

What do you mean by "a bit strange"?

How did you define your structure? What is the size of your sales array?

Posting a small complete program that illustrates the problem would probably help.

Also, how do I line up the chart in the output so its 8 neat columns?

I'd use functions from the <iomanip> header file like setw() to help line up the columns.

I've removed the end of line at the end of the loop and it prints correct

Where are you removing the end of line character within the entry loop? Remember cin is not the same stream as the customers stream.



By "strange" I mean incorrect. The output should match the text file exactly. Here is what the text file looks like:

Barack Obama DC 100 50 300 2000
Bill De Blasio NY 250 100 80 5000
Kirsten Gillibrand NY 50 100 200 1000
Chris Chrystie CT 100 200 300 5000
Loretta Lynch DC 50 80 200 1000

First Name, Last Name, State, Sales Years 0, Sales Year 1, Sales Year 2, Units

Thats 7 items (all separated by a tab). The output has to simply display these 7 items in tabular format, along with an additional 8th column known as totalSales (sum of sales of the 3 years). In my output, the sales Year 2 (i.e. the THIRD year of sales) and the totalSales is coming out wrong.

Here is the complete program I have so far. If you make the text file, and run it, you'll see the incorrect output:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <string>
#include <fstream>


using namespace std;

//delcaring the file
ifstream customers;

class cust{
    public:
        string first, last, state;
        double sales[2], totalSales;
        int units;
};

// Prototype Functions

void printcust(cust customer[], int aSize);

int main()
{
    // opening and checking the file
    /*************************************/
    customers.open("customers.txt");
    if(!customers.is_open())
    {
        cout << "FILE NOT OPENED";
        return 0;
    }
    /*************************************/

    // declaring object
    cust customer[10];

    string first, last, state;
    double sales[2], totalSales=0;
    int units;

    for(int i=0; i<5; i++)
    {
        customer[i].totalSales = 0;

        getline(customers, customer[i].first, '\t');
        getline(customers, customer[i].last, '\t');
        getline(customers, customer[i].state, '\t');
        customers >> customer[i].sales[0] >> customer[i].sales[1] >> customer[i].sales[2] >> customer[i].units;
            for(int n=0; n<3; n++)
            {
                customer[i].totalSales+=customer[i].sales[n];
            }

    }

printcust(customer, 5);

cin.get();

}

void printcust(cust customer[], int aSize)
{

for(int i=0; i<aSize; i++)
{
    cout << customer[i].first << "\t" << customer[i].last << "\t" << customer[i].state << "\t"
        << customer[i].sales[0] << " " << customer[i].sales[1] << " " << customer[i].sales[2]
        << "\t" << customer[i].units << "\t" << customer[i].totalSales;
}

return;
}

Last edited on
In my output, the sales Year 2 (i.e. the THIRD year of sales) and the totalSales is coming out wrong.

That's probably being caused by the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class cust{
    public:
        string first, last, state;
        double sales[2], totalSales;
        int units;
};
...


    for(int i=0; i<5; i++) // Line 41
    {
        customer[i].totalSales = 0;

        getline(customers, customer[i].first, '\t');
        getline(customers, customer[i].last, '\t');
        getline(customers, customer[i].state, '\t');
        customers >> customer[i].sales[0] >> customer[i].sales[1] >> customer[i].sales[2] >> customer[i].units;


Look how you declared sales[] with a size of 2, yet you try to read three sales figures. So your valid sales[] would be sales[0] and sales[1]. Using sales[2] would be accessing the array out of bounds.

Run it and notice the incorrect output:

It would be easier if you would just cut and paste your output into the post.


Look how you declared sales[] with a size of 2, yet you try to read three sales figures. So your valid sales[] would be sales[0] and sales[1]. Using sales[2] would be accessing the array out of bounds.



Oh wow....

What an idiotic mistake. Thank you so much.

Now I can move on and do the rest. Hoping I can do the rest on my own, but If I have more questions, I'll be sure to post them here.

I really appreciate your help bro. Thank you.
Im facing a new problem now.

I added a function to sort the data alphabetically by first name. However, its not getting sorted correct.

Here is my complete code:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <string>
#include <fstream>


using namespace std;

//delcaring the file
ifstream customers;

class cust{
    public:
        string first, last, state;
        double sales[3];
        int units, totalSales;
};

// Prototype Functions
void printcust(cust customer[], int aSize);
void sortname(cust customer[], int aSize);

int main()
{
    // opening and checking the file
    /*************************************/
    customers.open("customers.txt");
    if(!customers.is_open())
    {
        cout << "FILE NOT OPENED";
        return 0;
    }
    /*************************************/

    // declaring object
    cust customer[10];

    string first, last, state;
    double sales[3];
    int units, totalSales;

    for(int i=0; i<5; i++) // reads 5 lines from file
    {
        // reads string text using tab deliminator
        getline(customers, customer[i].first, '\t');
        getline(customers, customer[i].last, '\t');
        getline(customers, customer[i].state, '\t');
        // reads int text from file
        customers >> customer[i].sales[0] >> customer[i].sales[1] >> customer[i].sales[2] >> customer[i].units;

        customer[i].totalSales = 0; // set total sales to 0 before adding to it

        for(int n=0; n<3; n++) // finds sum of all three years of sales
            {
                customer[i].totalSales+=customer[i].sales[n];
            }
    }

printcust(customer, 5);
sortname(customer, 5);
printcust(customer, 5);

cin.get();

}

// Prints object array
void printcust(cust customer[], int aSize) // prints all data
{

for(int i=0; i<aSize; i++)
{
    cout << customer[i].first << "\t" << customer[i].last << "\t" << customer[i].state << "\t"
        << customer[i].sales[0] << " " << customer[i].sales[1] << " " << customer[i].sales[2]
        << "\t" << customer[i].units << "\t" << customer[i].totalSales;
}

cout << endl;

return;
}

// Sorts alphabetically by first name
void sortname(cust customer[], int aSize)
{
    cust temp;

    for(int pass=1; pass<aSize; pass++)
        for(int i=0; i<aSize-1; i++)
            if(customer[i].first > customer[i+1].first)
                {
                    temp = customer[i];
                    customer[i] = customer[i+1];
                    customer[i+1] = temp;
                }
}



My output is:

Barack Obama DC 100 50 300 2000 450
Bill De Blasio NY 250 100 80 5000 430
Kirsten Gillibrand NY 50 100 200 1000 350
Chris Chrystie CT 100 200 300 5000 600
Loretta Lynch DC 50 80 200 1000 330

Bill De Blasio NY 250 100 80 5000 430
Chris Chrystie CT 100 200 300 5000 600
Kirsten Gillibrand NY 50 100 200 1000 350
Loretta Lynch DC 50 80 200 1000 330Barack Obama DC
100 50 300 2000 450


The top section is the original output, that one is correct. The bottom output is after the sort. Notice that the "Barack Obama" line is weirdly at the bottom when it should be at the top. Whats going on here?
Last edited on
It appears that you're not reading the file correctly. Remember when you use the extraction operator>> you leave any delimiters in the stream so you probably have a new line left in the stream when you loop back to the beginning of loop.

Im not following you. How exactly am I reading the file wrong?

Sorry, im a beginner. Please break it down for me.

Thank you.
Try printing each item you receive on it's own line as you retrieve them, then perhaps you will see what is wrong. Because you're switching from the extraction operator>> to getline() you need to be careful about removing the new line character left behind by the last extraction operation.

I printed out each item on its own line like you said:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
         // reads string text using tab deliminator
        getline(customers, customer[i].first, '\t');
        cout << customer[i].first << endl;
        getline(customers, customer[i].last, '\t');
        cout << customer[i].last << endl;
        getline(customers, customer[i].state, '\t');
        cout << customer[i].state << endl;
        // reads int text from file
        customers >> customer[i].sales[0];
        cout << customer[i].sales[0] << endl;
        customers >> customer[i].sales[1];
        cout << customer[i].sales[i] << endl;
        customers >> customer[i].sales[2];
        cout << customer[i].sales[2] << endl;
        customers >> customer[i].units;
        cout << customer[i].units << endl;


Here is the output I got:

Barack
Obama
DC
100
100
300
2000

Bill
De Blasio
NY
250
100
80
5000

Kirsten
Gillibrand
NY
50
2.65323e-307
200
1000

Chris
Chrystie
CT
100
2.65323e-307
300
5000

Loretta
Lynch
DC
50
6.23427e-307
200
1000


I dont understand how some items in my output can be wrong. If some items are being read wrong, then why did my original (unsorted) output of the data come out correctly? Not only then, even the sorted data came out correct, the only problem was the formatting. The data itself was correct.

Im seriously confused at this point. Further help would be appreciated.
I dont understand how some items in my output can be wrong.

You have an error in your printout because you used i instead of 1 for that one sales element.

The problem is that there is that extra space between your records.

Let's try changing your input loop to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        getline(customers, customer[i].first, '\t');
        // Print the decimal representation of the first character in the first name.
        cout << "FIRST: " << static_cast<int>(customer[i].first[0]) << " " << customer[i].first << endl;
        getline(customers, customer[i].last, '\t');
        cout << "SECOND: " << customer[i].last << endl;
        getline(customers, customer[i].state, '\t');
        cout << "STATE: " << customer[i].state << endl;
        // reads int text from file
        customers >> customer[i].sales[0];
        cout << "SALES 1: " << customer[i].sales[0] << endl;
        customers >> customer[i].sales[1];
//        cout << "SALES 2: " <<customer[i].sales[i] << endl;
        cout << "SALES 2: " <<customer[i].sales[1] << endl;   // NOTICE THIS CHANGE AS WELL.
        customers >> customer[i].sales[2];
        cout << "SALES 3: " <<customer[i].sales[2] << endl;
        customers >> customer[i].units;
        cout << "UNITS: " << customer[i].units << endl;


Your output should appear something like:
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
55
56
57
58
FIRST: 66 Barack ////// Notice the first character is correct 66 is the decimal representation for 'B'.....
SECOND: Obama
STATE: DC
SALES 1: 100
SALES 2: 50
SALES 3: 300
UNITS: 2000
FIRST: 10    /////// Notice that the first character of the name is decimal 10, which is the new line character not 'B'.................................
Bill
SECOND: De Blasio
STATE: NY
SALES 1: 250
SALES 2: 100
SALES 3: 80
UNITS: 5000
FIRST: 10 
Kirsten
SECOND: Gillibrand
STATE: NY
SALES 1: 50
SALES 2: 100
SALES 3: 200
UNITS: 1000
FIRST: 10 
Chris
SECOND: Chrystie
STATE: CT
SALES 1: 100
SALES 2: 200
SALES 3: 300
UNITS: 5000
FIRST: 10 
Loretta
SECOND: Lynch
STATE: DC
SALES 1: 50
SALES 2: 80
SALES 3: 200
UNITS: 1000
Barack  Obama   DC      100 50 300      2000    450

Bill    De Blasio       NY      250 100 80      5000    430

Kirsten Gillibrand      NY      50 100 200      1000    350

Chris   Chrystie        CT      100 200 300     5000    600

Loretta Lynch   DC      50 80 200       1000    330


Bill    De Blasio       NY      250 100 80      5000    430

Chris   Chrystie        CT      100 200 300     5000    600

Kirsten Gillibrand      NY      50 100 200      1000    350

Loretta Lynch   DC      50 80 200       1000    330
Barack  Obama   DC      100 50 300      2000    450


Notice how your "table" is also containing extra spaces between the records?

This is being caused because you are switching between the extraction operator and getline(). The extraction operator leaves the end of line character in the file to be consumed by your next getline operation. If you consume this end of line character you should be okay. The reason Barack Obama is at the end of the sorted list is because Barack doesn't start with the end of line character.

This is the output when I consume this end of line character with ignore() at the end of the loop:
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
FIRST: 66 Barack
SECOND: Obama
STATE: DC
SALES 1: 100
SALES 2: 50
SALES 3: 300
UNITS: 2000
FIRST: 66 Bill
SECOND: De Blasio
STATE: NY
SALES 1: 250
SALES 2: 100
SALES 3: 80
UNITS: 5000
FIRST: 75 Kirsten
SECOND: Gillibrand
STATE: NY
SALES 1: 50
SALES 2: 100
SALES 3: 200
UNITS: 1000
FIRST: 67 Chris
SECOND: Chrystie
STATE: CT
SALES 1: 100
SALES 2: 200
SALES 3: 300
UNITS: 5000
FIRST: 76 Loretta
SECOND: Lynch
STATE: DC
SALES 1: 50
SALES 2: 80
SALES 3: 200
UNITS: 1000
Barack  Obama   DC      100 50 300      2000    450
Bill    De Blasio       NY      250 100 80      5000    430
Kirsten Gillibrand      NY      50 100 200      1000    350
Chris   Chrystie        CT      100 200 300     5000    600
Loretta Lynch   DC      50 80 200       1000    330

Barack  Obama   DC      100 50 300      2000    450
Bill    De Blasio       NY      250 100 80      5000    430
Chris   Chrystie        CT      100 200 300     5000    600
Kirsten Gillibrand      NY      50 100 200      1000    350
Loretta Lynch   DC      50 80 200       1000    330


I added this line just before the end of the loop to solve the problem.
customers.ignore(100, '\n');


Thank you very much. My program works fine and I understand what the problem was. Thank you also for introducing me to the ignore function.


Just one last question:

I now have three "tables". Problem is, they look like a mess. How do I line them up into neat columns, so all the state names are in one line, as well as the other pieces of information.

I tried using setw but it does not seem to work. For example, I used setw(5) for the state names but that just moved all the states over to the right. It didn't line them up.

Below is my complete code:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>


using namespace std;

//delcaring the file
ifstream customers;

class cust{
    public:
        string first, last, state;
        double sales[3];
        int units, totalSales;
};

// Prototype Functions
void printcust(cust customer[], int aSize);
void sortname(cust customer[], int aSize);
void sortsales(cust customer[], int aSize);

int main()
{
    // opening and checking the file
    /*************************************/
    customers.open("customers.txt");
    if(!customers.is_open())
    {
        cout << "FILE NOT OPENED";
        return 0;
    }
    /*************************************/

cout.setf(ios::fixed, ios::floatfield);

    // declaring object
    cust customer[10];

    string first, last, state;
    double sales[3];
    int units, totalSales;

    for(int i=0; i<5; i++) // reads 5 lines from file
    {
        // reads string text using tab deliminator
        getline(customers, customer[i].first, '\t');
        getline(customers, customer[i].last, '\t');
        getline(customers, customer[i].state, '\t');
        // reads int text from file
        customers >> customer[i].sales[0] >> customer[i].sales[1] >> customer[i].sales[2] >> customer[i].units;
        customers.ignore(); // discard newline character left behind by extraction operator

        customer[i].totalSales = 0; // set total sales to 0 before adding to it

        for(int n=0; n<3; n++) // finds sum of all three years of sales
            {
                customer[i].totalSales+=customer[i].sales[n];
            }

    }

cout << "ORIGINAL DATA:" << endl << endl;
printcust(customer, 5);

cout << "SORTED ALPHABETICALLY BY FIRST NAME:" << endl << endl;
sortname(customer, 5);
printcust(customer, 5);

cout << "SORTED IN DESCENDING ORDER BY TOTAL SALES" << endl << endl;
sortsales(customer, 5);
printcust(customer, 5);

cin.get();

}

// Prints object array
void printcust(cust customer[], int aSize) // prints all data
{

    cout << "First\tLast\tStates\tSales-1\tSales-2\tSales-3\tUnits\tTotal Sales" << "\n\n";
for(int i=0; i<aSize; i++)
{
    cout << customer[i].first << "\t" << customer[i].last << "\t" << setw(5) << customer[i].state << "\t"
        << setprecision(0)  << setw(5) << customer[i].sales[0] << " " << setprecision(0) << setw(6) << customer[i].sales[1]
        << " " << setprecision(0) << setw(7) << customer[i].sales[2] << "\t" << customer[i].units
        << "\t" << customer[i].totalSales << endl;
}

cout << "\n\n\n";

return;
}

// Bubble sorts alphabetically by first name
void sortname(cust customer[], int aSize)
{
    cust temp;

    for(int pass=1; pass<aSize; pass++)
        for(int i=0; i<aSize-1; i++)
            if(customer[i].first > customer[i+1].first)
                {
                    temp = customer[i];
                    customer[i] = customer[i+1];
                    customer[i+1] = temp;
                }
    return;
}

// Bubble sorts by descending order of sales
void sortsales(cust customer[], int aSize)
{
    cust temp;

    for(int pass=1; pass<aSize; pass++)
        for(int i=0; i<aSize-1; i++)
            if(customer[i].totalSales < customer[i+1].totalSales)
                {
                    temp = customer[i];
                    customer[i] = customer[i+1];
                    customer[i+1] = temp;
                }
    return;
}




And here is my output:

ORIGINAL DATA:

First Last States Sales-1 Sales-2 Sales-3 Units Total Sales

Barack Obama DC 100 50 300 2000 450
Bill De Blasio NY 250 100 80 5000 430
Kirsten Gillibrand NY 50 100 200 1000 350
Chris Chrystie CT 100 200 300 5000 600
Loretta Lynch DC 50 80 200 1000 330



SORTED ALPHABETICALLY BY FIRST NAME:

First Last States Sales-1 Sales-2 Sales-3 Units Total Sales

Barack Obama DC 100 50 300 2000 450
Bill De Blasio NY 250 100 80 5000 430
Chris Chrystie CT 100 200 300 5000 600
Kirsten Gillibrand NY 50 100 200 1000 350
Loretta Lynch DC 50 80 200 1000 330



SORTED IN DESCENDING ORDER BY TOTAL SALES

First Last States Sales-1 Sales-2 Sales-3 Units Total Sales

Chris Chrystie CT 100 200 300 5000 600
Barack Obama DC 100 50 300 2000 450
Bill De Blasio NY 250 100 80 5000 430
Kirsten Gillibrand NY 50 100 200 1000 350
Loretta Lynch DC 50 80 200 1000 330

Its not shown here cause the formatting doesn't get copied, but I think you get the idea.

Some states are lines up, others are not. Some sales are lined up, other are not. Sames with untis and Total Sales. Setw moves that entire set of data to the right, instead of lining up each individual piece of info. How do I get around this and line up my tables and make them look neat and easy to read?



Last edited on
Can anyone help me with this? How do I align the tables?
Topic archived. No new replies allowed.