string output with struct dynamic array

Beginner here, obviously.

Could anyone help me understand what I would need to do to fix my code. When it gets to input contributor name, it skips to the ptr[1].names and never allows me to put the first name. If I cin.get();, it will just output garbage in the donation loop.

Not looking to have you give me the answer, just help me to understand what I should be looking to do to fix it.

I most likely made some very elementary mistakes, so your patience with me is definitely 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
44
45
46
47
48
49
50
51
52
53
  #include <iostream>

using namespace std;

struct donors
{
	char names[127];
	double money;
};

int main()
{
	// Set struct array value through user input
	cout << "Enter the number of contributors: ";
	int donor{};
	cin >> donor;

	//create pointer to dynamic struct array
	donors* ptr = new donors[donor];

	//clear screen after initial input
	system("CLS");

	//Enter contributors name
	{
	for (int i = 0; i < donor; i++)
		{
			cout << i + 1<< ") Enter contributors name: ";
			cin.getline(ptr[i].names, 127);
		}
	//Enter donor contribution ammount
	for (int j = 0; j < donor; j++)
		{
			cout << j + 1 << ") Enter contribution ammount: ";
			cin >> ptr[j].money;
		}
	cout << endl;
	//Loop through each struct and print to screen
	for (int y = 0; y < donor; y++)
		{
			cout << "Name " << y+1 << "  :  "<< ptr[y].names;
			cout << "\tDonation " << " :  " << ptr[y].money << endl;
			cout << endl;
		}
	}
	//delete pointer array
	delete [] ptr;

	//delete dangling pointer
	ptr = 0;
}

closed account (48T7M4Gy)
When you use getline() you need to clear the cin stream buffer by using cin.ignore() before cin.getline(). cin.fail() is also used before a getline to clear any stream errors. Checkout the tutorials here for more detail.

Also, as a suggestion, consider removing some/all of your comments because they are redundant. It is clear what the code lines are doing without them. It would be better to have a couple of lines at the start giving a brief but clear purpose, input/output statement about the program.
Last edited on
OK, since this is a beginner forum, figured it best to share what I learned

cin >> is an amazing part of c++, the >> does two things, takes in the input that is requested and returns what is not requested. In my case, I was asking for a cin >> donor, which is an int. What >> was returning was the newline it was creating. Then when I followed that cin >> with a getline, well, the fist thing it got was that newline, which is why it was skipping over the first part of the loop.

Possibly I didn't explain it as well as a seasoned vet, I have only been learning for a month now, but hopefully my code before (original post) and after (below) illustrated what is needed to remove that return from the >>.

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
#include <iostream>
#include <string>
using namespace std;

struct donors
{
	string names;
	double money;
};

int main()
{
	int donor = 0;
	cout << "Enter the number of contributors: ";

// the .get() will remove the return from the >> stream
	(cin >> donor).get();
	system("CLS");

	donors* ptr = new donors[donor];

	for (int i = 0; i < donor; i++)
	{
		cout << i + 1 << ") Enter contributors name: ";
// buffer is empty, thanks to the .get() above, so my getline is only the string, which i want
		getline(cin, ptr[i].names);

		cout << i + 1 << ") Enter contribution ammount: ";

// following the process of keeping the buffer clear as I will loop back to the getline
		(cin >> ptr[i].money).get();
	}
	cout << endl;

	for (int y = 0; y < donor; y++)
		{
			cout << "Name " << y+1 << "  :  "<< ptr[y].names;
			cout << "\t\tDonation " << " :  " << ptr[y].money << endl;
			cout << endl;
		}
	delete [] ptr;
	ptr = 0;
}
There are several ways of removing the end of line character from the stream. There is the ignore() function and you can also use the ws manipulator to skip the leading whitespace.

getline(cin >> ws, ptr[i].names);

Also I notice you started using the std::string instead of the C-strings, good. Now I recommend you use std::vector instead of the dynamic memory allocation.

yeah, the lesson had me using array when vectors would have been ideal.

as i am getting more confident, i am leaving the using namespace std out of my code and using the :: more and more. as funny as it may sounds (read), the :: was very intimidating to me as i tried to make sense of terminology, syntax, and usage. i have so far to go, but feel my footing is getting firmer in the fundamentals.

regarding ignore, fail, and ws.
i read up on those and did see how they would fix the bug. but since I had yet to learn those, i simply stayed on the beaten trail until i get a little stronger sword to forge my own path. :)

btw, thanks for visiting my post. having a mentor is always a good thing to have as I definitely need one when i get confused.

t

Topic archived. No new replies allowed.