我正在编写一个程序,通过插入3个整数来识别用户可以制作的三角形。之后,根据它所经历的条件和陈述,它确定它们可以制作的三角形是平衡(所有边都相同),还是SCALENE(没有边相同),或者ISOSCELES(双面相同)。用户在每次询问时输入1-15cm之间的值。如果用户键入低于或高于限制的任何内容,程序会建议他们无法完成并且只是停止。
这是我的代码
/*** 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);
}
下图是编译和运行程序时的结果。
基本上,无论我是插入有效整数还是无效整数,它仍然会提供与屏幕截图相同的结果。
我还在学习C所以我可能会在这里和那里错过任何一件事,所以任何帮助都非常感激。
此外,我希望能够添加条件while循环,以阻止用户插入不正确的值或在需要整数时插入字符。我将在何处插入while循环,我将如何编写它?
更新1。 我已更新了代码部分
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)
所有回复都指导我同样的问题和答案。我已经分别更新了代码,它在第二个屏幕截图中看到的效果非常好。
我也测试了每个三角形的值,它完全正常。
还有另外一件事我遇到过。当测试插入除整数之外的值时,它会出现类似下面的屏幕截图。
我知道我必须插入一个条件来阻止某人插入除整数之外的任何东西,但这就是我有点绊倒的地方。如果没有while循环函数,我不太清楚如何做到这一点。任何想法?
更新2:我已经更新了我的代码,以便浮点数可以被视为有效,因为三角形可以有一个浮点整数。然而..
通过这样做,代码中的while
循环条件仍然会在要求用户输入sideB
和sideC
的值后立即显示该语句。任何想法如何解决?
另外
当测试只插入null
值或按Enter键时,程序没有任何反应。我们如何才能使用户不能将null
作为值?
更新3:
调试后,我在更新2之后发现了问题。我刚刚将%d
更改为%f`并修复了该问题。仍在使用空值或不允许输入空格键来解决问题。如果有人对此有所了解。请让我知道
答案 0 :(得分:5)
if(sideA || sideB || sideC <=0)
这不会测试你的想法。它被解析为
if ( (sideA) || (sideB) || (sideC <= 0) )
因此如果sideA
非零,或者sideB
非零,或者sideC
为负数或零,则测试为真。
如果您习惯使用布尔类型的其他编程语言,您可能会认为像sideA
这样的表达式不是布尔值,因此这应该会触发类型错误。但是C有效地将整数视为布尔值:C中的布尔值实际上是一个整数值,它是0(表示假)或1(表示真)。例如,如果sideC <= 0
小于0,则sideC
的值为1,否则为0。如果a || b
且a
均为0,则b
的值为0,否则为{。
C没有任何内置构造来测试三个值中的一个是否为负数。最明确的表达方式是
if (sideA <= 0 || sideB <= 0 || sideC <= 0)
你在其他if
陈述中犯了类似的错误。
答案 1 :(得分:1)
正如@ Gilles所解释的那样 (完全可靠的归功于他这么好的解释)
if(sideA || sideB || sideC <=0)
正在检查
if ( (sideA) || (sideB) || (sideC <= 0) )
应该是
if(sideA <=0 || sideB<=0 || sideC <=0)
您的其他if语句也是错误的,例如
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)
所有这些都可能有效,但它们没有达到您对它们的期望。这些可以通过将它们更改为
来解决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) )
所以,你的代码应该是
#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);
}
我根据您的问题更新
编辑了代码 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' );
}
现在,让我们解释一下这段代码。
从man引用,scanf()
的返回类型如下
这些函数返回成功匹配和分配的输入项的数量,可以少于提供的数量,或者在早期匹配失败的情况下甚至为零。
如果在任何一个输入结束之前到达输入结束,则返回值EOF 第一次成功转换或匹配失败。 EOF是 如果发生读错误也会返回,在这种情况下会出错 设置流的指示符(请参阅ferror(3)),并设置errno 表明错误。
在这种情况下,我们不会遇到EOF(至少我希望我们不会),所以我会跳过那部分。
因此,在您的情况下,如果scanf("%d", &sideB)
成功将值分配给sideB
,则scanf()
将返回1,因此我使用循环中给出的条件来生成循环只要scanf()
没有返回1,就会继续。
现在让我们进入
while ( (ch=getchar()) != '\n' );
getchar()
从stdin读取一个字符(标准输入设备,在你的情况下是你的键盘,或者当缓冲区中已存在某些东西时从输入缓冲区读取),但与你期望的有点不同
scanf("%d", &sideB)
不会将除整数之外的任何内容分配给sideB
(因为您正在使用%d
)。那么,当我们输入一个角色时会发生什么。好吧,字符和空格(空格,换行符等)保留在输入缓冲区中。然后,你的下一个scanf()
将尝试从缓冲区中读取,并遇到该字符并且不会将其分配并将其保留在缓冲区中,因此,所有剩余的scanf()
将执行相同的操作(因为他们有%d
。请注意,如果有%s
类型说明符,它将读取字符)。因此,为了防止出现这种错误,我使用了getchar()
。{/ p>
现在,回到代码
while ( (ch=getchar()) != '\n' );
现在,scanf()
读取缓冲区中留下的所有尾随字符和空格都被getchar()
读取,直到遇到'\n'
,因此在其他方面,while循环继续执行直到从缓冲区中读取'\n'
,从而刷新缓冲区以确保缓冲区中没有新行或字符,否则,下一个scanf()
将尝试从缓冲区读取会遇到它,因此,由于%d
类型说明符,它只是将所有这些字符留在缓冲区中,因此实际上没有存储任何值。所以,我使用while循环来刷新缓冲区。
@ Weather Vane指定的小细节也很重要
希望你能够理解所有这些(我不擅长解释所以请原谅我,如果我说的话没有意义)
希望这可以帮助你......
答案 2 :(得分:1)
你仍然错过了一个技巧:程序让我输入一个边1,1和3的三角形,告诉我它是一个有效的等腰三角形,当它不是时。这种三角形不可能存在。它需要一个额外的测试,所以确保任何两个方面的总和大于第三个
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");
}
为循环添加了伪代码:
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