Filling Vectors

Hi, trying to write some code to fill a list of customers and purchase amounts, I used a do/while to collect input, but for some reason on the second go-around it skips over the getline(cin) for the customer name and just skips straight over to the purchase amount. Am I missing something? I've been doing these for like 3 straight days so I've been missing obvious stuff

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
  #include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

vector<double> amount;
vector<string> name;

void printList()
{
    for(int i = 0; i < amount.size(); i++)
    {
        cout << name[i] << " || ";
        cout << amount[i] << endl;
    }
}

void inputData()
{
    string cust;
    double purch;

    cout << "Customer Name: ";
    getline(cin, cust);
    cout << "Purchase Amount: ";
    cin >> purch;

    if(!cin.fail() && cust != "Q")
    {
        name.push_back(cust);
        amount.push_back(purch);
    }
    

}

int main()
{
    cout << "Cashier: please enter names and purchase amounts, or enter Q to quit.\n";

    do
    {
        inputData();

    } while (!cin.fail());
    
    
    printList();

}


This isn't a completed program by any means, I'm just going through my textbook trying to learn how to use vectors and I'm basically printing out the contents to verify they're being filled properly.
Mixing getline and cin's >> operator can cause the newline to remain in the input buffer after the cin >> call.

In inputData(), simply add cin.ignore(); after cin >> purch;

1
2
3
4
5
    cout << "Customer Name: ";
    getline(cin, cust);
    cout << "Purchase Amount: ";
    cin >> purch;
    cin.ignore();
Last edited on
Got it, thank you! Really new to C++, only programming experience I have is PHP/SQL so these little intricacies in how the data is handled are what gets me.
Hmm... I must be missing something else. I'm like 90% of the way to finishing this one but for some reason my string return function that spits out the name of the customer with the largest purchase is stopping my do/while loop in the previous function and says that the first purchase amount/name combo inputted is the largest.

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
#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

vector<double> amount;
vector<string> name;

/** Prints a list of names and purchase amounts
 * no params, no return values
 */

void printList()
{
    for(int i = 0; i < amount.size(); i++)
    {
        cout << fixed << setprecision(2);
        cout << setw(15) << name[i] << " || ";
        cout << setw(8) << amount[i] << endl;
    }
}

/** Fills a given vector with customer names and purchase amounts
 * @param vector<double> amt (purchase amount)
 * @param vector<string> buyer (customer name)
 */

void inputData(vector<double>& amt, vector<string>& buyer)
{
    string cust;
    double purch;
    bool more;

    do
    {
        cout << "Purchase Amount: ";
        cin >> purch;
        //clear input buffer so we're able to enter another name on the next round
        cin.ignore();
        //check to see if user quits, if so we don't need to collect another name
        if(!cin.fail())
        {
            cout << "Customer Name: ";
            getline(cin, cust);
        }
        
        //add data to vectors if user hasn't quit
        if(!cin.fail())
        {
            buyer.push_back(cust);
            amt.push_back(purch);
        }
        else
        {
            //set bool to false if user quits
            more = false;
        }
    }
    while(more);
}

/** Determines which customer out of data from two corresponding vectors made the largest purchase
 * @param vector<double> sales (Amount of purchases)
 * @param vector<string> customers (name of customers)
 * @return string result (returns string with name of customer w/largest purchase)
 */

string name_of_best_customer(vector<double> sales, vector<string> customers)
{
    string result;
    for(int i = 0; i < sales.size(); i++)
    {
        int largest = 0;
        if(sales[i] > largest)
        {
            sales[i] = largest;
            result = customers[i];
        }
    }
    return result;
}

int main()
{
    cout << "Cashier: please enter purchase amounts and names, or enter Q as an amount to quit.\n";

    inputData(amount, name);
    printList();
    
    cout << "\nThe customer with the largest purchase is: " << name_of_best_customer(amount, name) << endl;

    system("pause");
    return 0;
    

}


For example, if I input 86753.09 and "Tommy Tutone" as the input, it'll stop the input gathering loop and just print out "The customer with the largest purchase is: Tommy Tutone"

What exactly in the name_of_best_customer function is causing the inputData() function to terminate?
dakotad8218 wrote:
Really new to C++, only programming experience I have is PHP/SQL so these little intricacies in how the data is handled are what gets me.
Yeah, sides effects like these aren't very intuitive. I would say the vast majority of people run into this issue when they are first learning, myself included.

An alternative solution is instead of cin.ignore() to remove the newline, you can do:
1
2
3
4
    cout << "Customer Name: ";
    getline(cin >> ws, cust);
    cout << "Purchase Amount: ";
    cin >> purch;

The cin >> ws call essentially removes all whitespace (ws) in the buffer.

Edit: This post was in response to your previous reply. I didn't read your latest reply yet.
Last edited on
In response to your latest post: One possible issue is that you never initialize bool more; to a proper value.
You should do: bool more = true;

But also, your logic for finding the largest value is wrong. Your "largest" variable is reset to 0 each time within the loop. You want largest to keep track of what the largest amount found so far is, so it needs to not reset each loop.
Last edited on
Got it, I suspected something with the boolean was going wrong within inputData. I'll also see if I can fix the initialization of the "largest" variable. Thanks for all your help so far!

EDIT: ah, I see, dumb mistakes are killing me yet again. Fixed the name_of_best_customer function... I had the variable assignment set up wrong. This is the new, working code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string name_of_best_customer(vector<double> sales, vector<string> customers)
{
    string result;
    double largest = 0;
    for(int i = 0; i < sales.size(); i++)
    {
        
        if(sales[i] > largest)
        {
            largest = sales[i];
            result = customers[i];
        }
    }
    return result;
}


it turns out I had it as sales[i] = largest; instead of largest = sales[i];, so it would just sit there and reset every element in the amounts(sales) vector to 0, so whatever the last entry was was considered the "largest" by the program. Fixed and done! works great. Thanks so much!
Last edited on
Here's the completed, tested code. I changed the input sentinel from Q to 0 but other than that it's the same, and is working properly.

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
#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

vector<double> amount;
vector<string> name;

/** Prints a list of names and purchase amounts
 * no params, no return values
 */

void printList()
{
    for(int i = 0; i < amount.size(); i++)
    {
        cout << fixed << setprecision(2);
        cout << setw(15) << name[i] << " || ";
        cout << setw(8) << amount[i] << endl;
    }
}

/** Fills a given vector with customer names and purchase amounts
 * @param vector<double> amt (purchase amount)
 * @param vector<string> buyer (customer name)
 */

void inputData(vector<double>& amt, vector<string>& buyer)
{
    string cust;
    double purch;
    bool more = true;

    do
    {
        cout << "Purchase Amount: ";
        cin >> purch;
        //clear input buffer so we're able to enter another name on the next round
        cin.ignore();
        //check to see if user quits, if so we don't need to collect another name
        if(purch != 0)
        {
            cout << "Customer Name: ";
            getline(cin, cust);
        }
        
        //add data to vectors if user hasn't quit
        if(purch != 0)
        {
            buyer.push_back(cust);
            amt.push_back(purch);
        }
        else
        {
            //set bool to false if user quits
            more = false;
        }
    }
    while(more);
}

/** Determines which customer out of data from two corresponding vectors made the largest purchase
 * @param vector<double> sales (Amount of purchases)
 * @param vector<string> customers (name of customers)
 * @return string result (returns string with name of customer w/largest purchase)
 */

string name_of_best_customer(vector<double> sales, vector<string> customers)
{
    string result;
    double largest = 0;
    for(int i = 0; i < sales.size(); i++)
    {
        if(sales[i] > largest)
        {
            largest = sales[i];
            result = customers[i];
        }
    }
    return result;
}

int main()
{
    cout << "Cashier: please enter purchase amounts and names, or enter 0 as an amount to quit.\n";

    inputData(amount, name);
    printList();
    
    cout << "\nThe name of the customer with the highest purchase amount is: " << name_of_best_customer(amount, name) << endl;

    system("pause");
    return 0;
    

}
Topic archived. No new replies allowed.