Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Loop Issues With Code 2

Status
Not open for further replies.

eriktorres

IS-IT--Management
Apr 15, 2005
10
US
Coders,

I have been working on this code for the last few days. I have the just of the code complete, yet one issue still arises. This code needs to calculate the area of a triangle. The sides a, b, and c are provided by the users and the sides are divided by 2, then that answer is calculated to give the area. These formulas are as follows:
A = sqrt((s(s-a)(s-b)(s-c)) where s= ((a+b+c)/2)
If the answer within the sqrt is less then 0 then the numbers provided in a, b, and c do not make a triangle.

Here is what the issue is. The program will work ok it I type in numbers that provide a negative under the sqrt, and a prompt is outputted to the user giving them the error and re-prompts them to reinput data. But if I retype data that is correct, no zero under the sqrt, the output if not correct.

For exmample. Type 2 3 and 6, this should give you the reprompt. Now type 999 999 999, which should give your 432147.1, or there abouts, but all i get is "Here is the area of the triangle 'nan'" and not 432147.1. But if I type 999 999 999 the first time then I do get the right output.

I hope this makes sence. It seems to me that the issue is with the loop somewhere. Any help would be greatly appreciated. I am comipiling under GCC with the -lm.

Code:
************************************************
#include <stdio.h>
#include <math.h>


/****Demostrates Declerations****/
float aside;
float bside;
float cside;
float sides;
float area;
float insidearea;
void calcsides(void);
void calcarea(void);
void inputsides(void);
void scannum(void);

/****Main Function****/
main(){
inputsides();
calcsides();
calcarea();
//area = sqrt(insidearea);
printf("Here is the area of the triangle");
printf(" %.4f\n", area);
//printf(" %.4f\n", sqrt((sides*((sides - aside)*(sides - bside)*(sides - cside)))));
}

/****Function Definitions****/
void inputsides(void){
printf("**********************************************************\n");
printf("Please enter three sides A, B, and C to calculate the area\n");
printf("of the triangle, negative numbers will not be calculated!\n");
printf(">>");
scannum();
while(aside <= 0 || bside <= 0 || cside <= 0){
while(getchar() != '\n'){
}
printf("You have entenred an incorrect number!\n");
printf("Try again.\n");
printf(">>");
scannum();
}
calcsides();
}

void calcsides(void){

sides = ((aside + bside + cside) / 2);

}

void calcarea(void){

insidearea = (sides*((sides - aside)*(sides - bside)*(sides - cside)));
//area = sqrt(insidearea);
if (insidearea < 0){
printf("Error: Lengths do not form a triangle!\n");
printf("\n");
inputsides();
}

area = sqrt(insidearea);
}
void scannum(void){

scanf("%f %f %f", &aside, &bside, &cside);
}
***************************************************
 
Alas, it's a bad, untidy program logic. After warning message in calcarea() you invoke inputside() then immediately calculate (after 999 999 999) wrong area...

1. Don't use global variables. Your functions must get arguments then calculate expressions and return its values (no side effects).
2. Never mix interface (input/output), control and calculation logics. For example, your calcarea() not only calculates an area (its task) but send messages and makes inputs (so gets into trouble;)...

 
Apropos, never use float type in math calcs: use double (don't forget %lf format specifier in scanf() for doubles). You may get into trouble in more serious calculations: float precision is too small...
 
ArkM,

Please forgive my ignorance. I am new to C and clearly don't understand your first response. If I don't use global variables then how do I pass the info to other functions? Your #2, I assume you mean that I should then create functions which only perform one thing. But will these fix my issues? And if so, how? Thanks.
 
For example your calcarea function could be

Code:
double calcarea ( double sidea, double sideb, double sidec )
  {
  double insidearea;
  double sides = ( sidea + sideb + sidec ) / 2.0;

  if ( ( insidearea = (sides*((sides - aside)*(sides - bside)*(sides - cside))) ) > 0 )
    return sqrt ( insidearea )
  else
    return -1.0
  }

Then call it using
Code:
if ( ( result = calcarea ( sidea, sideb, sidec ) ) > 0 )
  printf ( "size = %f\n", result );
else
  printf ( "Not a triangle\n" );
BTW - I haven't tested this so it will almost certainly need debugging. I'm just showing you the principle.

Columb Healy
 
eriktorres,
do it in a spirit of columb's post (separate then rule;).
Let's see your snippet fragmet (of calcarea() function):
Code:
    if (insidearea < 0){
        printf("Error: Lengths do not form a triangle!\n");
        printf("\n");
        inputsides();
        }
    area = sqrt(insidearea);
Let's suppose you have insidearea < 0. Now you print the message then input new sides (may be wrong) then unconditionally calculate sqrt() (may be for negative argument).

Why? It's calcarea (i.e. calculate area?) function.
Calculate, not input.
Look on another side of this problem. All your functions have mnemonics names (it's good;). But we don't know where are source and target data for these functionality (they are outside functions contexts in globals). So to use these functions we must study all your codes - is it right?

Suppose we want (may be in future?) to reuse this triangle area handler in window application (why not?). Alas, it's impossible because of no printf() function in windows app environment. Is it right?..

And so on. If you separate interface and problem area calculations, you may never catch this error (input data ad hoc in the middle of calculations and forget to verify untrusty (by definition;) user input.

Good luck!
 
Sorry ArkM didn't mean to barge in on your replies - I got confused by the timestamps on the posts and assumed you would have logged out.

Columb Healy
 
columb,
that's OK, your post was actual. I was off line (time zone problem;)...
 
ArkM and columb,

Thank you for your posts. I really appreciate your input. I want to be a good coder so this information will be great. I now understand the previous posts. Thanks.

et
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top