Triangle Program

I have this program, and I haven't had adequate time to work on it. Not making excuses, but I've had a ton of HW in other courses that I assumed this program would be simple so I've put it off until now and it's due tomorrow.

I know my code is missing important syntax and is incomplete, I was attempting to do one thing at a time and come back and fill in the blanks, but now I am confused as to what to do. My program is in an infinite loop.

One thing I'd like to learn more of is how to pass by reference, especially the read function, I know I can only return one value, but how does reference work to read in three at one time?

Here's the problem for this program:

Write a program to read in three integers representing line lengths. Determine if the three line segments form a right triangle, or an acute or an obtuse or not a triangle. Allow the three numbers to be input in any order. An input number will be 1<= n <= 5000.

right triangle c2 = a2 + b2 where c is the longest side
acute triangle c2 < a2 + b2
obtuse triangle c2 > a2 + b2
not a triangle: sum of two sides is smaller than the longest side

Restrictions: Use a function to read in three values, a functions to test for which triangle and a function to print results.

Output: Print results, print out the three lengths and the relation that they hold.

Data for program: File: TriangleFile.txt

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

//Function Prototypes
int read(int);
int triangle(int, int, int);
void write(int,int,int,ofstream&);
void printheader(ofstream&);

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

void printheader(ofstream& out)
{
    out << "\tTriangle Program\n"
        << " Angles of the Triangle \t Type of Triangle\n";
}

int read(ifstream& inf)
{
    int a;
    inf >> a;
    return a;
}

int triangle(int a, int b, int c)
{
      if(((a+b)>c) || ((c+b)>a) || ((c+a)>b))
        out << endl << "Valid Triangle";
    else
        out << endl << "Not a Right Triangle";
}

void right(int a, int b, int c)
{
      if(pow(c,2) == (pow(a,2) + pow(b,2)))
        out<<endl<<"This is a right triangle";
    else
    {
        out<<endl<<"This is not a right triangle";
        triangle(a,b,c);
    }
}

void acute(int a, int b, int c)
{
      if(pow(c,2) < (pow(a,2) + pow(b,2)))
        out << endl << "Acute Triangle";
    else
    {
        out << endl << "Not Acute";
        triangle(a,b,c);
    }
}

void obtuse(int a, int b, int c)
{
      if(pow(c,2) > (pow(a,2) + pow(b,2)))
        out << endl << "Obtuse Triangle";
    else
    {
        out << endl << "Not Obtuse";
        triangle(a,b,c);
    }
}

int LARGEST(int a, int b, int c)
{
    return max(max(a,b),c);
}

void write(int a, int b, int c, ofstream& out)
{
    out << " " << a << " x " << b << " x " << c
        << " " << triangle(a,b,c) << endl;
}

int main()
{
    int a, b, c,valid,right,acute,obtuse;

    printheader(out);
    while(!inf.eof())
    {
        c=LARGEST(a,b,c);
        a=read(inf);
        b=read(inf);
        c=read(inf);
        valid=triangle(a,b,c);
        right(a,b,c);
        acute(a,b,c);
        obtuse(a,b,c);
        write(a,b,c,out);
    }
return 0;
}

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
	Triangle Program
 Angles of the Triangle 	 Type of Triangle

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

Valid Triangle
Valid Triangle 7208908 x 7208908 x 7208908 5009696

and keeps going...
Hello CodeNovice01,

One thing I'd like to learn more of is how to pass by reference, especially the read function, I know I can only return one value, but how does reference work to read in three at one time?


There are two ways to pass variables to a function. "pass by value" and "pass by reference". Most of what you have don is "pass by value" except for the "printheader" and "write" functions with the "ofstream". Although the only way to pass a stream is by reference as you have learned to some degree.

Passing by value means that you are making a copy of the variable to use in the function. In somewhat simple terms. Passing by reference means you are using the variable that is defined where the function is called from.

There are three ways that I know of for passing by reference:
1
2
3
int read(ifstream& inf, int& side1, ...)
int read(ifstream& inf, int & side1, ...)
int read(ifstream& inf, int &side1, ...)

I tend to use and see the first example. The second example is acceptable, but not used as often. And when the compiler has a problem and creates an error message it tends to use the third example. At any time any method will work and is acceptable.

This way you can read the file for three numbers and it will read into the variables back where the function was called form. An example might be:
1
2
3
4
void read(ifstream& inf, int& side1, int& side2, int& side3)
{
     inf >> side1 >> side2 >>side3;
}

The variables are defined in the function parameters and there is no need to return anything. With out seeing the contents of the input file this is mostly a guess of what I think it would be.

The while(!inf.eof()) does not work the way you think it does. This has a good chance to process the last read twice before the condition figures out that "eof" has been set.
Since you are calling a function to read the file you could do something like this:
In "main"
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
    bool good{true};

    while (good)
    {
        good = read(a, b, c)  // <--- Use better names. Not single letters.

        if (!good)
            continue;  // <--- bypasses the rest of the code that follows and goes back to the while condition.

        // ... rest of code
    }

In the read function:
1
2
3
4
5
6
7
8
9
bool read(ifstream& inf, int& side1, int& side2, int& side3)
{
     inf >> side1 >> side2 >>side3;

     if (!inf)
         return false;

     return true;
}


If there is anything that you do not understand let me know.

Hope that helps,

Andy
Have you considered say
1
2
3
struct triangle {
    int a, b c;
};


Then you could do things like
1
2
3
4
5
triangle t = read(inf);
        right(t);
        acute(t);
        obtuse(t);
        write(t,out);


But it might be better to swap the references over for read, so it returns the stream reference.
1
2
3
4
5
ifstream& read(ifstream& inf, triangle &t)
{
    inf >> t.a >> t.b >> t.c;
    return inf;
}


Then main becomes a proper while loop which tests the file correctly.
1
2
while ( read(inf,myT) ) {
}

@salem c,

I knew there had to be a better way of doing that while loop. Since I do not tend to do my file reading that way I had not thought of that or seen it before.

Thanks for the tip.

Andy
Hello CodeNovice01,

After loading the program into my IDE, VS2017, I found that there were many errors that needed fixed first.

The function "Triangle()" is set up to return an "int", but inside the function it returns nothing.

In your functions "Right", "Acute" and "Obtuse" you are using the function "pow". This is not really needed as for something this simple you can just use if ((c * c) < (a * a) + (b * b)). Less work and overhead calling the function.

I also changed all the function names to start with a capital letter because of conflicts. Namely in "main" where you define the variable "right" as an "int" then later call the function "right", but the compiler does not know which of the three "right"s you are trying to use on line 94. Is it the variable "right" as defined in "main" or the function "right" or "std::right" from the "ioamnip" header file?

I also noticed that this program is quite similar, in some ways, to what you did in http://www.cplusplus.com/forum/beginner/264267/

Some of the concepts and responses are useful here and some of the code can easily be modified to work in this program.

One last thing I noticed is that you have defined your "ifstream" and "ofstream" as global variables, yet you pass them to functions that need them. As global variables all functions below their definition have access to the streams. There is no need to pass them to the functions.

I do have one question: how do you know that the "ifstream" is open and usable. The same thing I addressed in the above link to the last topic. Either I did not present this very well or you did not learn anything.

Hope that helps,

Andy
Topic archived. No new replies allowed.