Hi. I can't a small part of this program to work correctly; the square root function either returns a bunch of funny symbols OR it returns 0.00

On a side note, I have 2 questions:

1) If you have a structure nesting two other data structure types (like in my program where the structure contains an enumerated type as well as a union type) and you send this structure to a function, how do you write values directly into each of the fields via scanf?

2) Did I use the scanf and switch statements for the enumerated types correctly? I think I may have gotten that part to work on accident -.-

edit: forgot to add that the area for a triangle (according to this book) is sqrt(t(t - side1) * t(t - side2) * t(t - side3)) where t = (side1 + side2 + side3) / 2.

#include <stdio.h>
#include <math.h>

enum FIGURE {
	RECTANGLE = 1, CIRCLE, TRIANGLE
};

typedef union {
	double comp[3];
} DIM;

typedef struct {
	FIGURE shape;
	DIM size;
} DATA;

void get_area(DATA );

int main(void) {

	DATA input;

	while (input.shape != 4) {

		printf("*** Menu ***\n");
		printf("1: Rectangle\n");
		printf("2: Circle\n");
		printf("3: Triangle\n");
		printf("4: Quit\n");
		printf("Enter a selection: ");
		scanf("%d", &input.shape);

		switch(input.shape) {
			case RECTANGLE:
				printf("rectangle\n");
				printf("Enter the length: ");
				scanf("%lf", &input.size.comp[0]);
				printf("Enter the width: ");
				scanf("%lf", &input.size.comp[1]);
				get_area(input);
				break;
			case CIRCLE:
				printf("circle\n");
				printf("Enter the diameter: ");
				scanf("%lf", &input.size.comp[0]);
				get_area(input);
				break;
			case TRIANGLE:
				printf("triangle\n");
				printf("Enter length of side1: ");
				scanf("%lf", &input.size.comp[0]);
				printf("Enter length of side2: ");
				scanf("%lf", &input.size.comp[1]);
				printf("Enter length of side3: ");
				scanf("%lf", &input.size.comp[2]);
				get_area(input);
				break;
			case 4:
				printf("Have a nice day!\n");
				break;
			default:
				printf("Not a selection!\n");
		}
		printf("\n");
	}

	return 0;
}

void get_area(DATA input) {

	double area;

	switch(input.shape) {
		case RECTANGLE:
			area = input.size.comp[0] * input.size.comp[1];
			printf("Area = %.2lf\n", area);
			break;
		case CIRCLE:
			area = (input.size.comp[0] / 2) * (input.size.comp[0] / 2) * 3.14;
			printf("Area = %.2lf\n", area);
			break;
		case TRIANGLE:
			double t = (input.size.comp[0] + input.size.comp[1] + input.size.comp[2]) / 2;
			area = sqrt(t * ((t - input.size.comp[0]) * (t - input.size.comp[1]) *
			(t - input.size.comp[2])));
			printf("Area = %.2lf\n", area);
			break;
	}
}

Hi. I can't a small part of this program to work correctly; the square root function either returns a bunch of funny symbols OR it returns 0.00

Split the statement into two. Print the value that goes into the sqrt() function to see it's value, then call the function. If you need to, break the huge statement into smaller and smaller pieces until you nail down the problem. And verify the values going into comp are valid.

1) If you have a structure nesting two other data structure types (like in my program where the structure contains an enumerated type as well as a union type) and you send this structure to a function, how do you write values directly into each of the fields via scanf?

First of all, I wouldn't.... ;) I don't like scanf.
But it looks like you're using it OK.

2) Did I use the scanf and switch statements for the enumerated types correctly? I think I may have gotten that part to work on accident -.-

Happy accident. If you print the values after reading them, you'll know for sure.

Here's one of your problems:

double area;
/* [...] */
printf("Area = %.2lf\n", area);

Only scanf() uses %lf for doubles and %f for floats. printf() uses %f for both; it doesn't have a %lf.

DATA input;

	while (input.shape != 4) {

auto structures are not initialized, just like any other variable type. You need to initialize input.shape before you use it, lest it happen to be 4, skipping your loop completely and exiting the program. (The user would be surprised.) Most compilers warn about uninitialized variables such as this one if you turn on/up warnings.

switch(input.shape) {
		case RECTANGLE:
			area = input.size.comp[0] * input.size.comp[1];
			printf("Area = %.2lf\n", area);
			break;
		case CIRCLE:
			area = (input.size.comp[0] / 2) * (input.size.comp[0] / 2) * 3.14;
			printf("Area = %.2lf\n", area);
			break;
		case TRIANGLE:
			[b]double t[/b] = (input.size.comp[0] + input.size.comp[1] + input.size.comp[2]) / 2;
			area = sqrt(t * ((t - input.size.comp[0]) * (t - input.size.comp[1]) *
			(t - input.size.comp[2])));
			printf("Area = %.2lf\n", area);
			break;
	}

Declaring variables at the start of a case statement is like declaring a variable in the middle of a block (unless you use curly braces {} around the case contents, which I'm told isn't the best idea either), which is C99 . . . which may or may not be a problem.

area = (input.size.comp[0] / 2) * (input.size.comp[0] / 2) * 3.14;

I'm sure you can get a more accurate value of pi than 3.14 . . . you could use the non-standard M_PI or 3.14159265359 (from memory, so perhaps you'd better check it if you intend to use it :) ).

1) If you have a structure nesting two other data structure types (like in my program where the structure contains an enumerated type as well as a union type) and you send this structure to a function, how do you write values directly into each of the fields via scanf?

First of all, I wouldn't.... I don't like scanf.
But it looks like you're using it OK.

You have to do it as you've done it, reading each field individually. scanf can't read in a whole structure at once since it can't know what the structure contains.

Why don't you like using scanf()? I bet checking the return value and clearing the input buffer would solve many problems you've had with scanf in the past . . . .

This article has been dead for over six months. Start a new discussion instead.