Triangle-type checker, what am I missing?

Hey folks! I have a partially functioning triangle-checking program which wants to output everything as scalene. I cannot figure out why this is. My apologies I will not be able to reply for several hours as I head to work, I will check back in the evening. Thank you all for reading and thank you in advance for any replies!

Codeblocks returns no errors.

The MindTap compiler returns these errors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
main.cpp: In function ‘triangleType triangleShape(double, double, double)’:
main.cpp:69:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
main.cpp:59:24: warning: ‘equilateral’ may be used uninitialized in this function [-Wmaybe-uninitialized]
                 return equilateral;
                        ^~~~~~~~~~~
main.cpp:62:24: warning: ‘isosceles’ may be used uninitialized in this function [-Wmaybe-uninitialized]
                 return isosceles;
                        ^~~~~~~~~
main.cpp:65:28: warning: ‘scalene’ may be used uninitialized in this function [-Wmaybe-uninitialized]
                     return scalene;
                            ^~~~~~~
main.cpp:68:28: warning: ‘noTriangle’ may be used uninitialized in this function [-Wmaybe-uninitialized]
                     return noTriangle;
                            ^~~~~~~~~~


My apologies for all of my notes, this is only like the 2nd program I have written for my class that could not be passed with just algebraic operators, so I am a noob at this and still working on memorizing things.

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
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>

// enumerations need values set for return pointers
// from triangle identifier function, default would
// be 0-3, set different values?

// We need enumerations to prevent users from
// inputting stupid things like operations? Why would
// you do that?

// use 'if' function with specific return values for
// each type?

// Program could be easily expanded to include
// identifiers for special types of triangles
// and also ambigious cases

// angles can also be easily identified and could
// also be used as inputs for solving triangles

// Get a single function working first then expand
// May need to have a function to order inputs from
// smallest to largest

// Scalene parameters must be x < y < z, no value
// can be the same P.S. mindtap does not re-order
// its' inputs everytime so order does not matter for
// any situation

// Isosceles must have 2 equal sides, or x = y

// Equilaterals must have all 3 sides equal,  x = y
// = z this function should be the easiest to code,
// start here, isosceles next probably but it really
// does not matter much once a triangle is identified

// No triangle would mean the sum of 2 sides is
// smaller than or equal to the length of the
// longest side,
// you cannot have the sums of the lengths of the
// two smaller sides equal to the longer because it
// creates a line and not a triangle
//
//
// It appears MindTap is inputting it's values in
// ascending order, program can be simpler that
// previously assumed, no ordering necessary
// order just because?

using namespace std;

// enum declarations?

enum triangleType {scalene, isosceles, equilateral, noTriangle};

// double or float? How accurate do I want it?
// Mintap does not care.

triangleType triangleShape(double x, double y, double z);
void printTriangleShape(triangleType shape);

int main()
{
    double
        x,y,z;

    cout << "Enter first side: "<< endl;
    cin >> x;
    cout << "Enter second side: "<< endl;
    cin >> y;
    cout << "Enter third side: "<< endl;
    cin >> z;

//Compiler refuses to recognize greek characters
    triangleType O = triangleShape(x,y,z);
printTriangleShape(O);

    return 0;
}
// function must return a triangle enum? WHY?
triangleType triangleShape(double x, double y, double z)
{
   triangleType scalene, isosceles, equilateral, noTriangle;

// "if" statement probably needs to check if a triangle
// exists, if not, return noTriangle? Should this
// parameter be inside the triangle check or an "else if"
// statement outside of it if it fails triangle returns?

if (((x+y) > z) && ((x+z) > y) && ((y+z) > x))
    {
if (x == y && y == z)
   return equilateral;

 else if (x == y || x == z || y == z)
    return isosceles;

  else if (x<y && y<z)
     return scalene;

    }
       else if ((x+y) <= z || ((x+z) <= y) || ((y+z) <= x))
      return noTriangle;
    }

// print function of some sort, no return type
// needed, use void or something

void printTriangleShape(triangleType shape)
{
//Switch function to allow a cascade of conditions
//Consider a function work without a switch
//Smaller file size?

    switch (shape)
    {
case scalene: cout << "scalene" << endl;
 break;

  case isosceles: cout << "isosceles" << endl;
   break;

    case equilateral: cout << "equilateral!" << endl;
     break;

      case noTriangle: cout << "noTriangle"<< endl;
       break;
    }}



MindTap inputs the same numbers in the same order every time.

Checks are performed in the same order.

Inputs, outputs, and expected outputs from the MindTap checks:



Checks


Test Case: Complete
Output I:scalene

Input

2
4
5

Output

Enter first side:

2

Enter second side:

4

Enter third side:

5

scalene


Results
scalene

Expected Output
scalene




Test Case: Incomplete
Output II: noTriangle

Input

2
5
8

Output

Enter first side:

2

Enter second side:

5

Enter third side:

8

scalene


Results for noTriangle check

Expected Output
noTriangle

Unexpected Output
scalene




Test Case:Incomplete
Output III: isosceles

Input

2
2
3

Output

Enter first side:

2

Enter second side:

2

Enter third side:

3

scalene


Results for isosceles check

Expected Output
isosceles

Unexpected Output
scalene



Test Case: Incomplete
Output IV: equilateral

Input

8
8
8

Output

Enter first side:

8

Enter second side:

8

Enter third side:

8

scalene


Results for equilateral check

Expected Output:
equilateral

Unexpected Output:
scalene
Last edited on
a few things I spotted:
1) what happens if the first if statement is false?
if (((x+y) > z) && ((x+z) > y) && ((y+z) > x))
{...
}
...what do you return if you get HERE?

2) enum is a type AND a group of constants. you make 4 uninitialized variables, which you do not need. just return the values. (line 83: delete it). I think this is the main bug you asked about.

-------------
to answer some of your commented questions:
double or float? If you don't have a good reason to use float always use a double.

enum triangleType {scalene, isosceles, equilateral, noTriangle};
this makes scalene a constant == 0, isosceles a constant == 1, ... etc and they are at the global scope, so you can just use them. It also defines the type triangletype which can have any of those 4 values. It can be handy to order them ... if you made notriangle first, it would be zero, and then ... if (triangletypevariable) ... its a triangle (else its notriangle, the false/zero value).

//Compiler refuses to recognize greek characters
yes ... just spell them out ... alpha, beta, etc

// function must return a triangle enum? WHY?
triangleType triangleShape(double x, double y, double z)
-- because that is the type of the function. As I said above, its a TYPE that you created with the enum definition. The type of this function is triangletype, so you must return that type. just line int foo() returns an int, and return of "no good" does not work, because that is not an integer.

yes, when you do not return anything, void is correct. There is no 'or something' ... its either void, or it has a type that you must return a value into.

switch is not a function. It is a specialized version of if/else chains with slightly different rules (these rules can make it more efficient in high performance code).
-- it must only compare integers (enums count)
-- it will fall through if you do not put in breaks
-- it has a default catch-all condition


Let me know if cutting 83 fixes it.
Last edited on
jonnin thank you! That clears up some confusion. Removing line 83 fixed it.

The outputs are printing correctly but, I do still get a warning message.

1
2
3
4
main.cpp: In function ‘triangleType triangleShape(double, double, double)’:
main.cpp:43:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^


Does this mean a return type is not matching an output or that there is no output somewhere? Do I need another void somewhere?

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

using namespace std;

enum triangleType {scalene, isosceles, equilateral, noTriangle};

triangleType triangleShape(double x, double y, double z);
void printTriangleShape(triangleType shape);

int main()
{
    double
        x,y,z;

    cout << "Enter first side: "<< endl;
    cin >> x;
    cout << "Enter second side: "<< endl;
    cin >> y;
    cout << "Enter third side: "<< endl;
    cin >> z;

    triangleType Delta = triangleShape(x,y,z);
printTriangleShape(Delta);

    return 0;
}

triangleType triangleShape(double x, double y, double z)
{
        if (((x+y) > z) && ((x+z) > y) && ((y+z) > x))
          {
            if (x == y && y == z)
                return equilateral;

            else if (x == y || x == z || y == z)
                return isosceles;

                else
                    return scalene;
    }
            else if ((x+y) <= z || ((x+z) <= y) || ((y+z) <= x))
                    return noTriangle;
}
void printTriangleShape(triangleType shape)
{
    switch (shape)
    {
        case scalene: cout << "scalene" << endl;
            break;
            case isosceles: cout << "isosceles" << endl;
                break;
                case equilateral: cout << "equilateral!" << endl;
                    break;
                    case noTriangle: cout << "noTriangle"<< endl;
                        break;
    }
}

It means that there's a path through triangleShape() that doesn't return a value.

Just remove line 41 as the test isn't needed as it's already been done at line 30.
Last edited on
this is where the compiler's warning / code analysis breaks down.
you know, and I know, that your function always returns a value (well, I am assuming you did it right, and at a drive by it looks like you did) because you can show that in math, with a formal proof, or common sense, or whatever method you want ...

if (something)
return value
else if (!something)
return othervalue

to us, we can see that no matter what 'something' condition is, the function returns A value.
The compile can't see this.
it sees
if (condition) return, ok
if (condition) return, ok
... but no way to return a value if both conditions failed at the end of the function, NOT OK.
of course, as seeplus is saying, that means that we also know that the second condition is redundant. But the point is how the compiler looks at it, it can't tell for sure that the function is correct, so it throws a warning that maybe it is not.
In the triangleShape function, control will go past the end of the function if NaN is passed into the function, so the compiler is correct to complain here, although I agree that there are other times (especially with switch statements, even with default branches) where the compiler will unnecessarily complain, sometimes.

A NaN is never greater than something.
Nor is it less than something.
It is precisely not equal to anything.
Last edited on
Topic archived. No new replies allowed.