I'm writing a program which identifies what triangle a user can make by inserting 3 integers. After which based on the conditions and statements it goes through, it identifies whether the triangle they can make is a EQUILATERAL(all sides the same), or SCALENE(No sides the same), or ISOSCELES(Two sides the same). The user is to enter a value between 1-15cm in each occasion its asked. If the user types anything below or above the limit, the program would advise them it cannot be done and simply stop.
Here is my code
/*** Purpose: To create a C program which takes 3 integers and produces a result that shows which triangle(If valid) they have chosen.***/
#include <stdio.h>
int main()
{
/*** Declaring triangle variable sides ****/
float sideA;
float sideB;
float sideC;
char ch;
printf("Lets explore triangles! Please insert a value for side 'A' of your triangle.\n");
printf(" Ranging from 1-15cm.\n");
while(scanf("%d", &sideA) != 1)
{
printf("You inserted an incorrect value. Please insert a number ranging between 1-15cm, and try again.\n");
while ( (ch=getchar()) != '\n' );
}
printf(" Now insert a value for side 'B' of your triangle.\n");
while(scanf("%d", &sideB) != 1 )
{
printf("You inserted an incorrect value. Please insert a number ranging from 1-15cm, and try again.\n");
while ( (ch=getchar()) != '\n' );
}
printf(" And finally, insert a value for side C of your triangle ranging from 1-15cm.\n");
while(scanf("%d", &sideC) != 1 )
{
printf("You inserted an incorrect value. Please insert a number ranging from 1-15cm, and try again.\n");
while ( (ch=getchar()) != '\n' );
}
/*** List of conditions based on user input to identify if the triangle is valid and if so, what type of triangle they get***/
if(sideA <=0 || sideB<=0 || sideC <=0)
{
printf(" You cannot have a triangle with any side having a value of 0.\n");
}
else
if( (sideA+sideB<=sideC) || (sideB+sideC<=sideA) || (sideC+sideA<=sideB) )
{
printf("Your triangle is invalid!\n");
printf("The sum of every pair of sides must be greater than the third side of a triangle.!\n");
printf("Please try again.\n");
}
else
if( (sideA==sideC && sideB==sideC) || (sideB==sideA && sideC==sideA) || (sideC==sideB && sideA==sideB) ) /*** Code to determine EQUILATERAL TRIANGLE***/
{
printf(" Your input creates a valid EQUILATERAL triangle.\n");
}
else
if( (sideA == sideB ) || (sideB == sideC ) || (sideC == sideA ) )/*** Code to determine ISOSCELES TRIANGLE***/
{
printf("Your input creates a valid ISOSCELES triangle.\n");
}
else
if( (sideA!= sideB) && (sideB != sideC) )/*** Code to determine SCALENE triangle ***/
{
printf("Your input creates a valid SCALENE triangle.\n");
}
else
{
printf("You have inserted invalid range of values, as a result your triangle is invalid.\n");
printf("Please restart the program by closing it and opening it again to retry\n.");
printf("Goodbye.\n");
}
return(0);
}
The image below is the result of when the program is compiled and running.
Basically whether i insert a valid integer or invalid integer, it still gives the same result as the screenshot.
I'm still learning C so I may be missing a thing here and there, so any help is really much appreciated.
Also I want to be able to add a conditional while loop in order to stop the user from inserting an incorrect value or inserting a character when an integer is required. Where about's would I insert the while loop and how would I write it exactly?
UPDATE 1. I have updated the code section
if(sideA <=0 || sideB <=0 || sideC <=0)
{
printf(" You cannot have a triangle with any side having a value of 0.\n");
}
else
if(sideA >15 || sideB >15 || sideC >15)
All responses directed me to the same issue and answer. I have updated the code respectively and it works perfectly fine as seen in the second screenshot.
Also I tested the values for each triangle and it works perfectly fine.
There is one other thing I have come across. When testing to insert a value other than an integer, it comes up with something like the screen shot below.
I know I have to insert a condition to stop someone inserting anything other than an integer however that's where I'm a little stumbled. I'm not quite sure how to do that without a while loop function. any ideas?
UPDATE 2: I have updated my code to so that float number can be seen as valid since triangles can have a float integer. However..
By doing so, the while
loop condition in the code still makes the statement appear right after asking the user to enter a value for sideB
and sideC
. Any ideas how to fix?
Also
When testing just inserting a null
value or pressing enter, nothing happens to the program. How can we make it so that by a user cannot have null
as a value?
UPDATE 3: After debugging I found the issue after Update 2. I just changed %d
to %f` and that fixed that issue. Still figuring out the issue with null values or not allowing the enter of spacebar. If anyone has idea regarding this. Please let me know
if(sideA || sideB || sideC <=0)
This doesn't test what you think it does. It's parsed as
if ( (sideA) || (sideB) || (sideC <= 0) )
so the test is true if sideA
is nonezero, or if sideB
is nonzero, or if sideC
is negative or zero.
If you're used to other programming languages with a boolean type, you might think that an expression like sideA
isn't a boolean, so this should trigger a type error. But C effectively treats integers as booleans: a boolean in C is in fact an integer value that is either 0 (meaning false) or 1 (meaning true). For example, the value of sideC <= 0
is 1 if sideC
is less than 0, and 0 otherwise. The value of a || b
a || b
is 0 if a
and b
are both 0 and 1 otherwise.
C doesn't have any built-in construct to test if one of three values is negative. The clearest way to express that is
if (sideA <= 0 || sideB <= 0 || sideC <= 0)
You made a similar mistake in other if
statements.
As explained very well by @ Gilles ( full credit goes to him for such a nice explanation )
if(sideA || sideB || sideC <=0)
is checking
if ( (sideA) || (sideB) || (sideC <= 0) )
it should be
if(sideA <=0 || sideB<=0 || sideC <=0)
Your other if statements are wrong as well, like
if(sideA || sideB || sideC >15)
if(sideA && sideB==sideC || sideB && sideC==sideA || sideC && sideA==sideB)
if(sideA==sideB || sideB==sideC || sideC==sideA)
if(sideA!= sideB && sideC || sideB!= sideC && sideA || sideC!= sideA && sideB)
All of these might be valid, but they do not do what you expect of them. These can be solved by changing them to
if(sideA>15 || sideB>15 || sideC >15)
if( (sideA==sideC && sideB==sideC) || (sideB==sideA && sideC==sideA) || (sideC==sideB && sideA==sideB) )
if( (sideA == sideB) || (sideB == sideC) || (sideC == sideA)
if( (sideA!= sideB) && (sideB != sideC) )
So, your code should be
#include <stdio.h>
int main()
{
/*** Declaring triangle variable sides ****/
int sideA;
int sideB;
int sideC;
char ch;
printf("Lets explore triangles! Please insert a value for side 'A' of your triangle.\n");
printf(" Ranging from 1-15cm.\n");
while(scanf("%d", &sideA) != 1 )
{
printf("Please enter a number\n");
printf("Lets explore triangles! Please insert a value for side 'A' of your triangle.\n");
printf(" Ranging from 1-15cm.\n");
while ( (ch=getchar()) != '\n' );
}
printf(" Now insert a value for side 'B' of your triangle ranging from 1-15cm.\n");
while(scanf("%d", &sideB) != 1 )
{
printf("Please enter a number\n");
printf(" Now insert a value for side 'B' of your triangle ranging from 1-15cm.\n");
while ( (ch=getchar()) != '\n' );
}
printf(" And finally, insert a value for side C of your triangle ranging from 1-15cm.\n");
while(scanf("%d", &sideC) != 1 )
{
printf("Please enter a number\n");
printf(" And finally, insert a value for side C of your triangle ranging from 1-15cm.\n");
while ( (ch=getchar()) != '\n' );
}
/*** List of conditions based on user input to identify if the triangle is valid and if so, what type of triangle they get***/
if(sideA <=0 || sideB<=0 || sideC <=0)
{
printf(" You cannot have a triangle with any side having a value of 0.\n");
}
else
if(sideA>15 || sideB>15 || sideC >15)
{
printf("Please insert a value between 1cm-15cm only\n.");
}
else
if( (sideA==sideC && sideB==sideC) || (sideB==sideA && sideC==sideA) || (sideC==sideB && sideA==sideB) ) /*** Code to determine EQUILATERAL TRIANGLE***/
{
printf(" Your input creates a valid EQUILATERAL triangle.\n");
}
else
if( (sideA == sideB) || (sideB == sideC) || (sideC == sideA) )/*** Code to determine ISOSCELES TRIANGLE***/
{
printf("Your input creates a valid ISOSCELES triangle.\n");
}
else
if( (sideA!= sideB) && (sideB != sideC) )/*** Code to determine SCALENE triangle ***/
{
printf("Your input creates a valid SCALENE triangle.\n");
}
else
{
printf("You have inserted invalid range of values, as a result your triangle is invalid.\n");
printf("Please restart the program by closing it and opening it again to retry\n.");
printf("Goodbye.\n");
}
return(0);
}
I've edited the code as per your question Update
while(scanf("%d", &sideB) != 1 )
{
printf("Please enter a number\n");
printf(" Now insert a value for side 'B' of your triangle ranging from 1-15cm.\n");
while ( (ch=getchar()) != '\n' );
}
Now, lets explain this piece of code.
Quoting from man , the return type of scanf()
is as follows
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set indicate the error.
In this case, we are not going to encounter EOF ( at least I hope we don't ), so I will skip that part.
So, in your case, if scanf("%d", &sideB)
successfully assigns the value to sideB
, then scanf()
will return 1, so I use the condition as given in the loop to make the loop continue as long as scanf()
doesn't return 1.
Now lets move onto
while ( (ch=getchar()) != '\n' );
getchar()
reads a character from stdin ( the standard input device, which in your case would be your keyboard, or from the input buffer when something is already present in the buffer ), but a little differently than you expect.
scanf("%d", &sideB)
does not assign anything other than integers to sideB
( as you are using %d
). So, what happens when we enter a character. Well, the characters and whitespaces ( spaces, newlines, etc ) remain in the input buffer. Then, your next scanf()
would try to read from the buffer, and encounter the character and would not assign it and leaves it in the buffer, and hence, all the remaining scanf()
's would do the same ( as they have %d
. Note that if there was a %s
type specifier, it would read the characters ). So, in order to prevent such errors, I used that while loop with the getchar()
.
Now, the coming back to the code
while ( (ch=getchar()) != '\n' );
Now, all the trailing characters and whitespaces left behind in the buffer by scanf()
are read by getchar()
, until a '\\n'
is encountered, so in otherwords, the while loop keeps on executing until a '\\n'
is read from the buffer, thereby, flushing the buffer to ensure that no newline or character is left in the buffer, or otherwise, the next scanf()
would attempt to read from the buffer and would encounter it, and hence, due to the %d
type specifier, it just leaves all of those characters in the buffer, and hence no values are actually stored. So, I used that while loop to flush the buffer.
The small detail specified by @ Weather Vane is also Important
Hope you are able to understand all of that ( I'm not good at explaining so please forgive me if what I have said doesn't make sense )
Hope this helps you.....
You have still missed a trick in this: the program lets me input a triangle with sides 1, 1 and 3 and tells me it is a valid isosceles triangle, when it is NOT. Such triangle cannot exist. It needs an additional test so ensure the sum of any two sides is greater than the third
else
if( (sideA+sideB<=SideC) || (sideB+sideC<=SideA) || (sideC+sideA<=SideB) ) /*** check triangle is even possible ***/
{
printf("Your input cannot be a triangle because the sum of every pair of sides must be greater than the third side.\n");
}
Added pseudo code for a loop:
do {
ok = true
get 3 inputs
if input fails
ok = false
else if test 1 fails
print message 1
ok = false
else if test 2 fails
print message 2
ok = false
...
} while (!ok)
if 3 sides equal
print equilateral message
else if 2 side equal
print isosceles message
else
print scalene message
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.