How to find the largest and use the smaller numbers?

Update:
Updated the code to what I have currently. The only thing I need help with is figuring out how after I read in the 3 numbers, how to decipher which is the largest and which 2 are the smallest. And use those numbers in their respective functions.


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
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
using namespace std;

//Function Prototypes
void WRITE(int, int, int,int,int, double, ofstream&);
void PRINT(ofstream&);
int READ(int);
int AREA(int, int, int);
int GIRTH(int, int);
int LARGEST(int, int, int);
double COST(int);
int DIMENSION(int, int);

//File I/O
ofstream out("Shipping.out");
ifstream inf("Shipping.in");

//PrintHeader FUNCTION prints the header atop the program output.
void PRINT(ofstream& out)
{
    out << "\tShipping Box Program\n"
        << "Height x Depth\t Length  \tArea  Shipping Dimension\t Charges\n"
        << setprecision(2) << fixed;
}

//read FUNCTION reads in the data from the infile.
int READ(ifstream& inf)
{
    int a;
    inf >> a;
    return a;
}

//largest FUNCTION finds the largest value of the 3 numbers.
int LARGEST(int a, int b, int c)
{

    return max(max(a,b),c);
}

//space FUNCTION computes the area.
int AREA(int w,int h, int l)
{
    return w*h*l;
}

//sides FUNCTION calculates the girth of the box.
int GIRTH(int s1, int s2)
{
    return (s1 + s2) * 2;
}

//shipping_dimension FUNCTION calculates the inches to find the cost.
int DIMENSION(int g, int l)
{
    return g + l;
}

//shipping_cost FUNCTION calculates the cost for the box.
double COST(int sd)
{
    return 0.87 * sd;
}

//write FUNCTION prints to the file
void WRITE(int a, int b, int c, int d, int e, double f, ofstream& out)
{
    out << " \t" << a << "x" << b << "\t\t " << c << " \t\t" << d
        << " \t\t" << e << "  \t\t\t $" << f << endl;
}

//main FUNCTION does all the work by calling the appropriate function.
int main()
{
    int D1,D2,D3,width,length,height,area,
        shipdim,sd,small1,small2,total,girth;

    PRINT(out);

    while(!inf.eof())
    {
      D1=READ(inf);
      D2=READ(inf);
      D3=READ(inf);
      length=LARGEST(D1,D2,D3);
      girth=GIRTH(D1,D2);
      area=AREA(D1,D2,D3);
      shipdim=DIMENSION(girth,length);
      total=COST(shipdim);
      WRITE(D1,D2,D3,area,shipdim,total,out);
    }
out.close();
inf.close();
    return 0;
}


You are to write a program to calculate some information about a box for shipping.

You are to use Functions for this program.

You are to read in the length, width, and height of a box, compute the area of the box, compute the shipping dimension which is the sum of the girth and the length.

The girth is the sum of the two smallest sides times 2.

UPS charges $0.87 per 24 shipping inches.

Write a program to read in several boxes, print out their dimensions, area, shipping dimension and the cost for shipping.

Write a function for reading, a function for area, one for girth, one for length, one for shipping dimension, one for shipping cost and one for printing results. Print out in table format. See below.

Input file: Shipping.txt

Example input: 5 8 12 or 5 12 8 or 12 8 5 (ie you have to determine the two smaller dimensions)

Output:
Height x Depth Length Area Shipping Dimension Charges

5x8 12 480 20 $17.40

INFILE DATA:
1
2
3
4
5
6
7
8
9
5 6 12
15 12 13
2 5 4
15 8 2
24 18 15
15 18 24
7 6 5
5 5 5
10 15 9

CURRENT OUTPUT:
1
2
3
4
5
6
7
8
9
10
11
	Shipping Box Program
Height x Depth	 Length  Area    Shipping Dimension	 Charges
 	5x6      12 	360 		34  		 $29.00
 	15x12	 13 	2340 		69  		 $60.00
 	2x5	 4 	40 		19  		 $16.00
 	15x8	 2	240 		61  		 $53.00
 	24x18	15 	6480 		108 		 $93.00
 	15x18	 24 	6480 		90  		 $78.00
 	7x6	 5 	210 		33  		 $28.00
 	5x5	 5 	125 		25 		 $21.00
 	10x15	 9 	1350 		65  		 $56.00

Everything is correct except the order of the width, height, length.
Last edited on
Hello CodeNovice01,

Your functions look OK for now. I would suggesting changing the "float"s to "double"s. Especially since you are working with money.

In "main" I would add the line std::cout << std::fixed << std::showpoint << std::setprecision(2); so that your floating point numbers will output will show only two decimal points. This only need done once and will stay this way until changed.

In your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
	int
		printHeader(out);

	while (!inf.eof())
	{
		= read(inf);


	}

	out.close();
	inf.close();

	return 0;
}

The compiler does not care about white space, so line 3 starts with the "int" and ends with the semi-colon on line 4. This is either a poor attempt at a prototype, which would be in the wrong place, or you are missing the variables to go with the "int". And it is quite possible that some of the missing variables should be "double"s.

Your functions "printHeader()" and "read()" and "write()" all take a file stream as a parameter, but you have defined the file streams as global variables, so there is no need to pass them to the functions. As global variables the whole file has access to them. You are better to move lines 17 and 18 to inside "main" since everything is set up to pass them to the functions.

For the function "read()" it says that you want to return an "int". A function can only return ONE item, so your "return a,b,c;" will return the value of "c" because of the comma operator that you are using and not understanding. You could define the variables in main and pass them by reference.

In the while loop in "main" while(!inf.eof()) the condition will not work the way you are thinking and by the time the condition becomes "false" you will have processed the last read twice. What would work better is while(read(inf, width, length, height)) with all variables being passed by reference. Then if you enter the while loop you can process the data. If the read should return a failed state the while loop will fail.

I noticed the function:
1
2
3
4
float shipping_cost(float cost)
{
	cost = 0.87 * 24;
}

This says it returns a "float", but the functions returns nothing. This should be a compile error. The other part is that "cost" is defined as a local variable and would be lost when the function ends.

Overall you have a good start, but need some refinement to work properly.

Once I load it up and compile I will have a better idea what else is wrong.

Hope that helps,

Andy
Hello CodeNovice01,

I had to make some changes, but I did get the read to work:

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
// Prototype.
bool read(std::ifstream& inFile, double& length, double& width, double& height);

// Function.
bool read(std::ifstream& inFile, double& length, double& width, double& height)
{
	inFile >> length >> width >> height;

	if (inFile)  // <--- To check if "inFile" is still good.
		return true;

	return false;  // <--- When "eof" is set.
}

// In "main"
while (read(inFile, length, width, height))
{
	std::cout
		<< " Length = " << std::setw(5) <<length
		<< "  Width = " << std::setw(5) << width
		<< "  Height = " << std::setw(5) << height
		<< "  Area = " << std::setw(6) << area(length, width, height) << '\n';

	
	//std::cout << std::endl; // <--- Used as a break point for testing.
}

I have used the "std::cout" for now to see what it is reading and how it is reading.

The first part of "main" looks 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
int main()
{
	double length{}, width{}, height{};
	double smallestSize{};

        // <--- Should have the file extension "txt" since they are text files.
	const std::string inFileName{ "Shipping In.txt" };
	const std::string outFileName{ "Shipping Out.txt" };

	std::ifstream inFile(inFileName);
	std::ofstream outFile(outFileName); // <--- At some point you may want
	                                    // "std::ofstream outFile(outFileName, std::ios::app);" to append the file.
					    // And not overwrite it each time it is opened. Or not.
	if (!inFile)
	{
		std::cout << "\n File " << std::quoted(inFileName) << " did not open" << std::endl;
		//std::this_thread::sleep_for(std::chrono::seconds(3));  // <--- Needs header files chrono" and "thread". Optional as is the header files.
		return 1;  //exit(1);  // If not in "main".
	}

	if (!outFile)
	{
		std::cout << "\n File " << std::quoted(outFileName) << " did not open" << std::endl;
		//std::this_thread::sleep_for(std::chrono::seconds(3));  // <--- Needs header files chrono" and "thread". Optional as is the header files.
		return 2;  //exit(2);  // If not in "main".
	}

	printHeader(outFile);

The first thing you need to do is get it to read the file so that you have something to work with. Notice how I have changed the variable names to something that is easier to follow.

Now you have something to work with when you call your other functions. Not all functions should be called from main. Some functions may need to call other functions to get the information that they need.

Hope that helps,

Andy
Andy,

I'm not sure what {} does at the end of your declared variables, but I doubt I can use that as of right now. Also, I can't use bool, professor said it's a no no. The code I had originally uploaded had a lot of obvious errors. Some I forgot to fix prior to my upload. We're also not allowed to use pass by reference yet, but we can pass by value. Meaning we aren't suppose to use & within the function. But I wasn't sure how else to read in or out my data without using ofstream& and ifstream&

Right now, my bigger concerns are: how to read the largest side(length) and take the other two numbers and use them in another function.
How to properly setup the "main" function to call the other functions properly.

Here is my code as of now:
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
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
using namespace std;

//Function Prototypes
void write(int, int, int,int,int, float, ofstream&);
void printHeader(ofstream&);
int read(int);
int area(int, int, int);
int girth(int, int, int);
int length(int, int, int);
float shipping_cost(float);
int shipping_dimension(int, int, int);

ofstream out("Shipping.out");
ifstream inf("Shipping.in");

void printHeader(ofstream& out)
{
    out << "\tShipping Box Program\n"
        << "Height/Depth\t Length  Area  Shipping Dimension\t Charges\n";
}
int read(ifstream& inf)
{
    int a,b,c;
    inf >> a >> b >> c;
    return a,b,c;
}
int largest(int a, int b, int c)
{
    return max(max(a,b),c);
}
int space(int w,int h, int l)
{
    return w*h*l;
}
int sides(int g, int s1, int s2)
{
    return g = (s1 + s2) * 2;
}
int shipping_dimension(int sd, int g, int l)
{
    return sd = g + l;
}
float shipping_cost(float cost, int sd)
{
    cost = 0.87 * sd;
}

void write(int a, int b, int c, int d, int e, float f, ofstream& out)
{
    out << " " << a << "x" << b << " " << c << " " << d
        << " " << e << " $" << f << endl;
}
int main()
{
    int dimension,width,length,height,l,area_total,shipdim,sd,small1,small2,total,girth;
    
    printHeader(out);

    while(!inf.eof())
    {
      dimension=read(inf);
      dimension=largest(width,height,length);
      if(!largest(width,height,length))
      {
          dimension=sides(girth,small1,small2);
      }
      area_total=space(width,height,length);
      shipdim=shipping_dimension(sd,girth,length);
      shipdim=shipping_cost(total,sd);
      write(width,height,length,area_total,shipdim,total,out);



    }
out.close();
inf.close();
    return 0;
}


This is my output, any clues on how to fix?

OUTPUT:
Shipping Box Program
Height/Depth Length Area Shipping Dimension Charges
8x98 4354992 -880653568 -2147483648 $7.41419e+008
8x98 4354992 -880653568 -2147483648 $7.41419e+008
8x98 4354992 -880653568 -2147483648 $7.41419e+008
8x98 4354992 -880653568 -2147483648 $7.41419e+008
8x98 4354992 -880653568 -2147483648 $7.41419e+008
8x98 4354992 -880653568 -2147483648 $7.41419e+008
8x98 4354992 -880653568 -2147483648 $7.41419e+008
8x98 4354992 -880653568 -2147483648 $7.41419e+008
8x98 4354992 -880653568 -2147483648 $7.41419e+008
Last edited on
I'm not sure what {} does at the end of your declared variables

It is "universal initialization." Something introduced in C++11, improved in C++14.

https://www.learncpp.com/cpp-tutorial/b-4-initializer-lists-and-uniform-initialization/

Uniform initialization is the preferred way to initialize variables now.

Instead of int x = 0; use int x { }; The blank initializer list defaults to zero because the variable is of type int.

int x { 5 }; assigns the value of 5 to x.

int x { 5.5 }; produces a compile error, trying to assign a floating point value to an int.

It produces an error in Visual Studio 2019, I don't know if GCC will have a warning or an error.

Thank you for that info Furry Guy.

Based on my output, I can see that the program reads the entire infile data, which is a plus. Now I need to figure out how to do the calculations correctly. That's typically my biggest issue to figure out.
Last edited on
In case of confusion, I have updated the post and code in the original post. It's the most current to what I have tried up to this point. The program runs, but the output is very wrong. I know it has to do with the functions/calculations, I'm calling them wrong, unsure how to properly call multi-functions within other functions. I know I did that in "main" but is it the same process in any other function within my program?

UPDATE:
I'm able to read in the data from the infile. But the calculations are the hardest part for me. And I need assistance with the largest number. The largest function doesn't appear to be working when I call it in "main", I must be doing something incorrectly.
Last edited on
CodeNovice01 wrote:
In case of confusion, I have updated the post and code in the original post


Please DON'T do that. Threads work forwards; it causes complete confusion if some responses no longer refer to what precedes them. Please put the entire latest version of your code BELOW this post and state exactly what your problem is for exactly what input.



while(!inf.eof())
Please don't do that either! The stream won't see the end-of-file marker until it tries to read from it, by which time you will be committed to doing the loop, the stream providing no new input, and variables retaining the values they had on the previous loop.


If you want to sum the two smallest, the easiest approach may be to ... sum the lot, then subtract the largest.


Also, your code is full of very small functions on similar bits of data with a lot of argument passing. Maybe you could consider classes and object-oriented programming? Just a thought.
Last edited on
@LastChance, we aren't to classes or object oriented just yet. We will get to it next semester.

The last issue I am having with this code is displaying the correct decimal value. I'm unsure to which calculation has the error.

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
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
using namespace std;

//Function Prototypes
void WRITE(int, int, int,int,int, double, ofstream&);
void PRINT(ofstream&);
int READ(int);
int AREA(int, int, int);
int GIRTH(int, int);
int LARGEST(int, int, int);
double COST(int);
int DIMENSION(int, int);
int SMALLEST(int, int, int);
int MIDDLE(int, int, int, int, int);

//File I/O
ofstream out("Shipping.out");
ifstream inf("Shipping.in");

//PRINT FUNCTION prints the header atop the program output.
void PRINT(ofstream& out)
{
    out << "\tShipping Box Program\n"
        << "Height x Depth\t Length  \tArea  Shipping Dimension\t Charges\n"
        << setprecision(2) << fixed;
}

//READ FUNCTION reads in the data from the infile.
int READ(ifstream& inf)
{
    int a;
    inf >> a;
    return a;
}

//LARGEST FUNCTION finds the largest value of the 3 numbers.
int LARGEST(int a, int b, int c)
{
    return max(max(a,b),c);
}

//SMALLEST FUNCTION returns the smallest value.
int SMALLEST(int a, int b, int c)
{
    return min(min(a,b),c);
}

//MIDDLE FUNCTION returns the middle value.
int MIDDLE(int a, int b, int c, int w, int l)
{
    if(a!=l && a!=w)
        return a;
    if(b!=l && b!=w)
        return b;
    if(c!=l && c!=w)
        return c;
}

//AREA FUNCTION computes the area.
int AREA(int w,int h, int l)
{
    return w*h*l;
}

//GIRTH FUNCTION calculates the girth of the box.
int GIRTH(int a, int b)
{
    return (a + b) * 2;
}

//DIMENSION FUNCTION calculates the inches to find the cost.
int DIMENSION(int g, int l)
{
    return g + l;
}

//COST FUNCTION calculates the cost for the box.
double COST(int sd)
{
    return 0.87 * sd;
}

//WRITE FUNCTION prints to the file
void WRITE(int a, int b, int c, int d, int e, double f, ofstream& out)
{
    out << " \t" << a << "x" << b << "\t\t " << c << " \t\t" << d
        << " \t\t" << e << "  \t\t\t $" << f << endl;
}

//main FUNCTION does all the work by calling the appropriate function.
int main()
{
    int D1,D2,D3,area,shipdim,total,girth,length,width,height;

    PRINT(out);

    while(!inf.eof())
    {
      D1=READ(inf);
      D2=READ(inf);
      D3=READ(inf);
      width=SMALLEST(D1,D2,D3);
      length=LARGEST(D1,D2,D3);
      height=MIDDLE(D1,D2,D3,length, width);
      girth=GIRTH(D1,D2);
      area=AREA(D1,D2,D3);
      shipdim=DIMENSION(girth,length);
      total=COST(shipdim);
      WRITE(width,height,length,area,shipdim,total,out);
    }
out.close();
inf.close();
    return 0;
}
Which input gives you which wrong value? Please be more precise about your error.

Your variable 'total' should be a double, should it not?

Your routine MIDDLE is definitely wrong: it won't return anything if all dimensions are equal.

If you want all of smallest, middle and largest of three numbers, wouldn't it be simpler just to sort them?
Last edited on
Hello CodeNovice01,

Sorry for the delay. When I say your latest code I had to start over checking.

Starting from the beginning.

In order to use the "min" and "max" functions I had to add the header file "<algorithm>".

In the function prototypes and then in the function definitions all the names are in all caps. This makes me think that they are variables defined as being constant. Generally function names are in all lower case letters. I do see a potential problem with the functions "area" and "girth" having a conflict with the variables "area" and "girth" in "main". You could give the function a slightly different name or just start the function names with a capital letter as I did at one point.

You have defined your "ifstream" and "ofstream" as global variables. Normally I would advise against this, but for this program and what you are not allowed to do it works. I will suggest changing the file names. Using "in" and "out" as the file extension is confusing and can be a problem if you try to open the file outside of the program. Both the input and output files ate text files and should have a ".txt" extension, so "Shipping In.txt" and "Shipping Out.txt" would be a better choice and you can still use the "in" and"out" for the different files.

You start your function definitions with void PRINT(ofstream& out) and int READ(ifstream& inf). Yet you once said
We're also not allowed to use pass by reference yet, but we can pass by value. Meaning we aren't suppose to use & within the function.
I find my-self perplexed by this and the fact that it is irrelevant in the first place. Both "?fstream"s are at global scope which means that every function that follows has access to them. There is no need to pass them to the functions. Which eliminates the need for "?fstream&" in the functions and prototypes. This also holds true for the "Write" function.

For testing purposed I changed the "Print" and "Write" functions to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void PRINT()
{
	out << "\tShipping Box Program\n"
		<< "Height x Depth\t Length  \tArea  Shipping Dimension\t Charges\n"
		<< setprecision(2) << fixed;

	std::cout << '\n' << std::setw(18) << ' ' << "Shipping Box Program\n\n"
		<< std::setw(35) << ' ' << "Shipping\n"
		<< "Height x Depth   Length    Area    Dimension   Charges\n";
}


void WRITE(int height, int width, int length, int d, int e, double f)
{
	out << " \t" << height << "x" << width << "\t\t " << length << " \t\t" << d
		<< " \t\t" << e << "  \t\t\t $" << f << endl;

	std::cout << std::setw(7) << height << "x" << std::setw(2) << width
		<< std::setw(11) << length
		<< std::setw(5) << ' ' << std::setw(5) << d // <--- Area
		<< std::setw(4) << ' ' << std::setw(5) << e // <--- ship dim
		<< std::setw(7) << ' ' << "$" << std::setw(6) << f << endl;
}

Noticed how I changed the variable names in the "Write" function. Sorry I did not get around to changing all the variable names as I should have. You may not be at a point to have learned about "std::setw()", but as I look at it if you include a header than everything available in thet header file is up for use. Otherwise you should have not been told about it.

The only function I found a problem with, and as lastchance noted, is in the "Middle" function" the logic of the if statements does not work all the time. lastchance said:
If you want to sum the two smallest, the easiest approach may be to ... sum the lot, then subtract the largest.
The same concept will work here. Sum all the values, (D1, D2, D3), and subtract the largest, (length) and subtract the smallest, (width) and the number remaining will be what, (height) will need.

Now inside "main" you have defined all your variables as "int"s, but this causes a problem with "total". The function "Cost" returns a double, but when you try to stuff a "double" into an "int" you loose information as the "int" can only hold the whole number and drops the decimal part. To work properly "total" should be defined as a double.

Again as lastchance pointed out:
while(!inf.eof())
Please don't do that either! The stream won't see the end-of-file marker until it tries to read from it, by which time you will be committed to doing the loop, the stream providing no new input, and variables retaining the values they had on the previous loop.

But if you insist on using this then learn how to do it properly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
D1 = READ();
D2 = READ();
D3 = READ();

while (!inf.eof())
{
	width = SMALLEST(D1, D2, D3);
	length = LARGEST(D1, D2, D3);
	height = MIDDLE(D1, D2, D3, length, width);

	girth = GIRTH(width, height);
	area = AREA(width, height, length);
	shipdim = DIMENSION(girth, length);
	total = COST(shipdim);

	WRITE(width, height, length, area, shipdim, total);

	D1 = READ();
	D2 = READ();
	D3 = READ();
}

By doing the successive reads at the end of the while loop you will catch "eof" at the proper time and only process what you have read.

After you have values for "width", "length" and "height" the variables "D1, D2 and D3" no longer have any useful purpose as the numbers they contain have no useful order.

After the changes the program produced this output:

                  Shipping Box Program

                                   Shipping
Height x Depth   Length    Area    Dimension   Charges
      5x 6         12       360       34       $ 29.58
     12x13         15      2340       65       $ 56.55
      2x 4          5        40       17       $ 14.79
      2x 8         15       240       35       $ 30.45
     15x18         24      6480       90       $  78.3
     15x18         24      6480       90       $  78.3
      5x 6          7       210       29       $ 25.23
      5x 5          5       125       25       $ 21.75
      9x10         15      1350       53       $ 46.11


You could arrange the numbers under "Height" and "Depth" differently if you want, but I think I would keep the "x"s in the same column.

This is the output using "std::cout". What is written to the file could still use some work as the file did not quite match what was sent to the display.

You actualy have a program that is very close to what you want. It just needs some minor changes along with some cosmetic changes if you want.

Hope that helps,

Andy
Topic archived. No new replies allowed.