Struct issues

I keep getting errors with my 'bidInfo getBid()' function. Which is part of a struct. The point of this function is to set the variables in the struct and return them. Im not sure where I have gone wrong. 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
struct bidInfo {
	string title;
	int fund;
	string vehicle;
	double bidAmount;
};

bidInfo getBid() {
    bidInfo temp;

    cout << "Enter title: ";
    cin.ignore();
    getline(cin, temp.title);

    cout << "Enter fund: ";
    cin >> temp.fund;

    cout << "Enter vehicle: ";
    cin.ignore();
    getline(cin,temp.vehicle);

    cout << "Enter amount: ";
    cin.ignore();
    string strAmount;
    getline(cin, strAmount);
    temp.bidAmount = strToDouble(strAmount, '$');

    return temp;
}

/**
 * Simple C function to convert a string to a double
 * after stripping out unwanted char
 *
 * credit: http://stackoverflow.com/a/24875936
 *
 * @param ch The character to strip out
 */
double strToDouble(string str, char ch) {
    str.erase(remove(str.begin(), str.end(), ch), str.end());
    return atof(str.c_str());
}
Hello b29hockey,

First off your code does not compile. I had to guess at what was missing and I am not sure if I am correct.

Also please give an idea of what information is to be used for the struct variables.

Line 12 is not needed there. At this point there is nothing in the input buffer to ignore, so it will ignore the first character of the "getline".

Line 16 should be followed with std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); because there will be a new line (\n) left in the input buffer.

Your use of std::cin.ignore() is using the defaults of (1, '\n'). The problem is that the input buffer may have more than one character and whatever is left will be put in the next variable. The above code will ensure that the entire input buffer will be cleared. You could also use something like std::cin.ignore(1000, '\n'); which should work fine.

You should find this works better:
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
BidInfo getBid()
{
	BidInfo temp;

	std::cout << "\n Enter title: ";
	//std::cin.ignore(); // <--- Not needed here. Will erase the first character of the next "getline".
	std::getline(std::cin, temp.title);

	std::cout << " Enter fund: ";
	std::cin >> temp.fund;
	// <--- Needed here before the next "getline".
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.

	std::cout << " Enter vehicle: ";
	std::getline(std::cin, temp.vehicle);

	std::cout << " Enter amount: ";
	//std::cin.ignore(); // <--- Not needed here. The "getline will leave an empty input buffer.
	std::string strAmount;
	std::getline(std::cin, strAmount);

	temp.bidAmount = strToDouble(strAmount, '$');

	// <--- An alternative to what you have. Enters direct into the struct and eliminates the need for the function.
	//std::cout << " Enter amount: $ ";
	//std::cin >> temp.bidAmount;
	//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.

	return temp;
}


A suggestion for your function:
1
2
3
4
5
6
7
double strToDouble(std::string str, char ch)
{
	str.erase(remove(str.begin(), str.end(), ch), str.end());

	return atof(str.c_str());
	//return stod(str); // <--- From "std::string".
}

The last line is a small change, but better to use what is available from the string class.

The comments in the code should explain what you need. If not let me know,

Hope that helps,

Andy
Hello b29hockey,

I was working on the program and realized a flaw.

In the function "getBid()"when you enter information for "strAmount" this is a std::string which means it will accept unformatted input of anything such as "$1000", "1000" and even "$a1000" and also "10a00".
The last would produce a double of (10).

The problem is when you try to convert "a1000" to a double it will produce a run time error because it can not convert the "a" to a number.

This is one of the few occasions that you can make use of the try/catch to keep the program from ending.

This is a general idea, but eventually you may want to put this in a loop until you get a valid number.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
double strToDouble(std::string str, char ch)
{
	str.erase(remove(str.begin(), str.end(), ch), str.end());

	try
	{
		return stod(str); // <--- From "std::string".
        }
	catch (const std::exception& e)
	{
		std::cout << "\n    Invalid number!." << std::endl;
		std::cout << "\n        " << e.what() << std::endl;
		std::cout << "\n    You entered: \"" << str << "\". Just a number please." << std::endl;
	}
}


Hope that helps,

Andy
Topic archived. No new replies allowed.