#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void perimeter(double, double, double, double *, double *);
double square(double, double, double, double);
void heights(double, double, double, double *, double *, double *, double);
void medians(double, double, double, double *, double *, double *);
void bisectors(double, double, double, double *, double *, double *, double);
int main()
{
char buffer[32];
double first_side = 0;
double second_side = 0;
double third_side = 0;
double per1;
double per2;
double height_to_firstside;
double height_to_secondside;
double height_to_thirdside;
double median_to_firstside;
double median_to_secondside;
double median_to_thirdside;
double bisector_to_firstside;
double bisector_to_secondside;
double bisector_to_thirdside;
for (int i = 0; i < 3; i++)
{
printf("Enter a number for side %d: ", i + 1);
fgets(buffer, sizeof(buffer), stdin); // Зчитуємо рядок
//Validation
if (strspn(buffer, "0123456789.") != strlen(buffer) - 1)
{
printf("Invalid input. Please enter other nums.\n");
return 0;
}
int dot_count = 0;
for (int j = 0; j < strlen(buffer); j++)
{
if (buffer[0] == '0' && buffer[1] != '.')
{
printf("Invalid input. Please enter other nums.\n");
return 0;
}
if (buffer[j] == '.')
{
dot_count++;
}
if (dot_count >= 2)
{
printf("Invalid input. Please enter other nums.\n");
return 0;
}
}
double input;
sscanf(buffer, "%lf", &input);
if (i == 0) // Зберігаємо значення в відповідній змінній
{
first_side = input;
}
else if (i == 1)
{
second_side = input;
}
else if (i == 2)
{
third_side = input;
}
/*int c;
while ((c = getchar()) != '\n' && c != EOF) {}
memset(buffer, 0, sizeof(buffer));*/
}
if ((first_side + second_side) < third_side || (second_side + third_side) < first_side || (first_side + third_side) < second_side)
{
printf("Unreal triangle, enter other nums\n");
return 0;
}
perimeter(first_side, second_side, third_side, &per1, &per2);
double area = square(first_side, second_side, third_side, per2);
heights(first_side, second_side, third_side, &height_to_firstside, &height_to_secondside, &height_to_thirdside, per2);
medians(first_side, second_side, third_side, &median_to_firstside, &median_to_secondside, &median_to_thirdside);
bisectors(first_side, second_side, third_side, &bisector_to_firstside, &bisector_to_secondside, &bisector_to_thirdside, per2);
//results
printf("Perimeter: %lf\n", per1);
printf("Semi-perimeter: %lf\n", per2);
printf("Square: %lf\n", area);
printf("Height for the first side: %lf\n", height_to_firstside);
printf("Height for the second side: %lf\n", height_to_secondside);
printf("Height for the third side: %lf\n", height_to_thirdside);
printf("Median for the first side: %lf\n", median_to_firstside);
printf("Median for the second side: %lf\n", median_to_secondside);
printf("Median for the third side: %lf\n", median_to_thirdside);
printf("Bisector for the first side: %lf\n", bisector_to_firstside);
printf("Bisector for the second side: %lf\n", bisector_to_secondside);
printf("Bisector for the third side: %lf\n", bisector_to_thirdside);
return 0;
}
void perimeter(double first, double second, double third, double *pPer1, double *pPer2)
{
*pPer1 = first + second + third;
*pPer2 = *pPer1 / 2;
}
double square(double first, double second, double third, double semi_perimeter)
{
double square_size;
square_size = sqrt(semi_perimeter * (semi_perimeter - first) * (semi_perimeter - second) * (semi_perimeter - third));
return square_size;
}
void heights(double first, double second, double third, double *pHeight_firstside, double *pHeight_secondside, double *pHeight_thirdside, double semi_perimeter)
{
*pHeight_firstside = 2 * (sqrt(semi_perimeter * (semi_perimeter - first) * (semi_perimeter - second) * (semi_perimeter - third))) / first;
*pHeight_secondside = 2 * (sqrt(semi_perimeter * (semi_perimeter - first) * (semi_perimeter - second) * (semi_perimeter - third))) / second;
*pHeight_thirdside = 2 * (sqrt(semi_perimeter * (semi_perimeter - first) * (semi_perimeter - second) * (semi_perimeter - third))) / third;
}
void medians(double first, double second, double third, double *pMedian_firstside, double *pMedian_secondside, double *pMedian_thirdside)
{
*pMedian_firstside = 0.5 * (sqrt((2 * second * second) + (2 * third * third) - (first * first)));
*pMedian_secondside = 0.5 * (sqrt((2 * first * first) + (2 * third * third) - (second * second)));
*pMedian_thirdside = 0.5 * (sqrt((2 * first * first) + (2 * second * second) - (third * third)));
}
void bisectors(double first, double second, double third, double *pBisector_firstside, double *pBisector_secondside, double *pBisector_thirdside, double semi_perimeter)
{
*pBisector_firstside = (2 / (second + third)) * (sqrt((second * third * semi_perimeter) * (semi_perimeter - first)));
*pBisector_secondside = (2 / (first + third)) * (sqrt((first * third * semi_perimeter) * (semi_perimeter - second)));
*pBisector_thirdside = (2 / (first + second)) * (sqrt((first * second * semi_perimeter) * (semi_perimeter - third)));
}
这是我的代码,正如你所看到的,我使用一个字符数组从用户那里获取值,然后验证它,最后将其转换为双精度型,但这一切都是在一个循环中完成的,所以我遇到了一个问题,我无法清除缓冲区,当用户输入第一个值时,然而,省略了接下来的两个,那么第一个值也被分配给了第二个和第三个。
我尝试使用fflush(stdin)
,但它不工作,我也尝试了这个:
int c;
while ((c = getchar()) != '\n' && c != EOF)
但它也不起作用,所以我甚至不知道我现在应该尝试什么。
2条答案
按热度按时间6ie5vjzr1#
你当然可以清除输入缓冲区。或者只是像预期的那样消耗数据。
fflush
未定义为输入。至少不是终端输入。从Linuxman
页面:它只为输出而定义,并不意味着
discard
任何东西。例如:您可以让stdout
的驱动程序等待\n
在tty
上打印该行,但随后程序结束。缓冲区中的字节无论如何都会被打印出来:OS
在结束时刷新输出缓冲区。如果在代码中需要立即真正打印数据,则有fflush
。一些
C
编译器接受fflush
作为输入流的扩展,AFAIK仅供学生使用。在
Windows
下,对于控制台输入,可以调用如文档中所述。在Linux上,我认为您可以搜索
ioctl
调用或termios
来执行相同的操作。只消耗所有输入数据
如果你消耗了所有的数据,那么输入缓冲区就不是你的代码所关心的了。
我会给你一个例子,重新排列你的代码。
封装
围绕数据编写代码。只要有机会就使用封装。这不仅仅是一个OOP花哨的词。这是一个强大的东西。
从你的代码:
程序中计算的值只有在有输入三角形时才有意义。如果一方的措施发生变化,所有值都无效。
所以...
想想这个:
这是你的数据。至于
msrs
,从您的代码使用
Triangle
的值INSIDE可以轻松地强制依赖关系。并且还可以在代码中处理任意数字或三角形。如何创建
Triangle
这是程序中
main
的起始代码。但在这里scanf
的单个调用读取3个度量C
样式中,如果三角形的度量值可以,则so_is_triangle()
返回1
so_get_measures()
计算所有三角形的参数考虑这些函数:
有明显的意义。
main
进行简单测试这样读起来更容易。
测试输出
关于
so_show_triangle
请注意,一个变量的12个printf比12个变量的单个printf慢数百倍。更难纠正或调整...
比较:
与
在例子中使用。
示例
C
完整代码kzmpq1sx2#
虽然您已经勇敢地尝试验证用户的输入,但它很难阅读,而且似乎给您带来了问题。当涉及超过50行代码时,可能会发生这种情况。
下面显示了一个使用
strtod()
将ASCII数字转换为double
的示例。这个库函数将作为第二个参数传递的指针设置为指向成功转换的浮点值之外。这段代码要求用户输入一个有效的正浮点数,也许加上前导空格,仅此而已。也许你会使用它并扩展它来满足你的需求:结果如下:
编辑:
我真诚地写了《勇敢的尝试》。然而,通过尝试 * 过滤掉 * 坏字符串,代码将拒绝“3.14153e5”(314153.000),因为您可能没有意识到这是一个有效的浮点数表达式。花时间学习标准库函数并试验它们的使用通常会更好。
关于您的代码和这里显示的代码之间的差异的另一个注解。请注意,此函数中的代码仅在使用变量时定义变量。这种做法减少了在声明和第一次使用之间上下滚动的需要。
编辑(不是OP问题的一部分)
计算功能很好,隔离了不同的导出结果,但它们相当冗长,因此很难 * 扫描 * 为正确和完整。
下面是同一函数的两个版本:
更少(正确)的代码是更好的代码。