Segmentation fault in C? Arrays, pointers, functions - c

Hi due to my lack of knowledge in C (second year in college). Compiler ate my code and built the app. But after accepting first value - numOfIntegers it stops working and debugging tells that the segmentation has been failed. SIGSEGV.
How to fix that?
There is the code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
/* -----------------------------------------
Program: Question 1
Author: Maggot #9
Email: maggot99999#gmail.com
ID: B00076450
Date: 16 September 2015
Purpose: Who knows?
------------------------------------------ */
void wait(int);
void controlMenu(int, int[]);
int sumOfIntegers(int, int[]);
int avgOfIntegers(int, int[]);
int prodOfIntegers(int, int[]);
int minInteger(int, int[]);
int maxInteger(int, int[]);
const char * getName (int value)
{
static char * arrayName[] = {"first","second","third", "fourth",
"fifth","sixth", "seventh", "eighth", "ninth", "tenth"};
static char badValue[] = "unknown";
if (value<10 && value>=0)
return arrayName[value];
else
return badValue;
}
int getValue(int numOfInteger)
{
int value;
wait(100);
printf("Please enter %s the value:", getName(numOfInteger));
scanf("%d",&value);
return value;
}
void prepare(int * numOfIntegers)
{
wait(300);
printf("Hey again that C stupid lang\n\n");
wait(200);
printf("Please enter how many values you want to put: ");
scanf("%d",numOfIntegers);
return;
}
void initialize(int numOfIntegers,int* arrayNum[])
{
int i;
for(i=0; i<(numOfIntegers); i++)
arrayNum[i] = getValue(i);
wait(500);
printf("\nPlease enter press any button to continue");
wait(100);
getch();
wait(600);
system("cls");
wait(200);
return;
}
int main()
{
int numOfIntegers;
prepare(&numOfIntegers);
int arrayNum[numOfIntegers];
initialize(numOfIntegers, &arrayNum[numOfIntegers]);
controlMenu(numOfIntegers, &arrayNum[numOfIntegers]);
return 0;
}
void controlMenu(int numOfIntegers, int arrayNum[])
{
int i;
char chooseNum;
printf("Please choose any of the following:\n\n1. The integers accepted\n2. The sum of the integers\n3. The average of the integers\n4. The product of the integers\n5. The smallest integer\n6. The largest integer\n0. Exit menu\n");
while(1)
{
chooseNum = getch();
switch(chooseNum)
{
case '0':
return;
case '1':
printf("\n>>> The integers are:");
for(i=0; i<(numOfIntegers); i++)
{
printf("\n>>> The %s is %d", getName((i+1)), arrayNum[i]);
}
break;
case '2':
printf("\n>>> The sum of integers is: %d", sumOfIntegers(numOfIntegers, &arrayNum[numOfIntegers]));
break;
case '3':
printf("\n>>> The average of integers is: %d", avgOfIntegers(numOfIntegers, &arrayNum[numOfIntegers]));
break;
case '4':
printf("\n>>> The product of integers is: %d", prodOfIntegers(numOfIntegers, &arrayNum[numOfIntegers]));
break;
case '5':
printf("\n>>> The smallest integer is: %d", minInteger(numOfIntegers, &arrayNum[numOfIntegers]));
break;
case '6':
printf("\n>>> The largest integer is: %d", maxInteger(numOfIntegers, &arrayNum[numOfIntegers]));
break;
default:
break;
}
printf("\n\n");
}
}
int sumOfIntegers(int numOfIntegers,int arrayNum[])
{
int sum=0;
for(int i=0; i<(numOfIntegers); i++)
sum += arrayNum[i];
return sum;
}
int avgOfIntegers(int numOfIntegers, int arrayNum[])
{
int average=0;
average = sumOfIntegers(numOfIntegers, arrayNum[numOfIntegers])/numOfIntegers;
return average;
}
int prodOfIntegers(int numOfIntegers, int arrayNum[])
{
int i,product=0;
for(i=0; i<(numOfIntegers); i++)
product *= arrayNum[i];
return product;
}
int minInteger(int numOfIntegers, int arrayNum[])
{
int i,smallest=0;
smallest = arrayNum[0];
for(i=1; i<(numOfIntegers); i++)
{
if(smallest>arrayNum[i])
smallest=arrayNum[i];
else
continue;
}
return smallest;
}
int maxInteger(int numOfIntegers, int arrayNum[])
{
int i,largest=0;
largest = arrayNum[0];
for(i=1; i<(numOfIntegers); i++)
{
if(largest<arrayNum[i])
largest=arrayNum[i];
else
continue;
}
return largest;
}
void wait(int ms)
{
Sleep(ms);
return;
}

I can see this fault in getName() which will access memory beyond the array bounds
if (value>10 || value<1)
return arrayName[value];
I believe you are using the wrong test, try
if (value <= 10 && value > 0)
return arrayName[value-1];
assuming value is in the range 1..10 as the textual array implies.
2) a fault in GetValue where you input into numOfInteger but return value, which is uninitialised.
3) in prepare the statement
scanf("%d",&numOfIntegers);
will not pass the input value back to the caller. You should have either passed a pointer to the variable, or returned the value input.
But there might be a lot else wrong. Build your program step by step, checking and trying to break it as you go (with absurd input). Pay attention to compiler warnings - the second fault I listed will generate one.
EDIT okay... let's examine function prepare which after removing noise is
void prepare(int numOfIntegers)
{
scanf("%d",&numOfIntegers);
return;
}
This inputs a value to the function parameter that was passed. This is legal, since you can use a function argument in the same way you can a local variable (perhaps subject to const qualification).
Although it's not a coding error, it does not achieve anything. 1) you usually pass an argument like this to be used by the function in some way, perhaps in its limits and/or in its prompt. 2) Altering the argument like this will not find its way back to the caller.
Here are two ways to deal with this.
A) the function returns the input value
int prepare(void)
{
int value;
scanf("%d", &value); // the address of value
return value;
}
...
int input = prepare();
printf("%d\n", input);
B) the function takes a pointer argument
void prepare(int *value)
{
scanf("%d", value); // value is already a pointer
}
...
int input;
prepare(&input);
printf("%d\n", input);

Related

How to pass an array from function to function

So I'm fairly new to programming in general and I am working on a project where I have to create a couple of functions.
Everything is fine with the first function but I can't figure out how to pass the values from the first function to the second function
I know that I need to use some pointers to solve the problem but I was just wondering if there was an easier way until i get the hang of using pointers.
Thanks in advance!
Here's my messy code
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <malloc.h>
#define START_SIZE 2
int number_of_branches=0;
typedef struct
{
int Month_num[12];
double sales[12];
bool active;
}Branch;
double function_one(void);
double function_two(void);
double function_three(void);
void function_four(void);
int main()
{
int User_Selection;
do
{
printf("1. Enter sales data.\n2. Add a record for a new branch.\n3. Delete record of an existing branch.\n4. Calculate total sales.\n5. Calculate percentage share of each branch.\n6. Determine the month of peak sales.\n7. Display sales of a specific month.\n8. Display sales of a specific branch.\n0. Done\n");
scanf("%i",&User_Selection);
switch (User_Selection)
{
case 0:
{
printf("Thankyou for your time :)\n");
break;
}
case 1:
{
function_one();
break;
}
case 2:
{
function_two();
break;
}
case 3:
{
function_three();
break;
}
case 4:
{
function_four();
break;
}
default:
{
printf("Please enter a valid input :)\n");
break;
}
}
}
while(User_Selection!=0);
}
double function_one(void)
{
//FILE *file = fopen("Sales.csv","a");
printf("Ender number of branches: ");
scanf("%d",&number_of_branches);
printf("\n");
Branch Branches[number_of_branches];
RecPointer r;
r = (RecPointer)malloc(sizeof(Rec));
//printf("%d",number_of_branches);
for(int b=0; b<number_of_branches; b++)
{
printf("Sales for branch %d: \n",(b+1));
for(int x=0;x<12;x++)
{
printf("Sales for month %d: ",(x+1));
scanf("%lf",&Branches[b].sales[x]);
//printf("\n%lf\n",Branches[b].sales[x]);
//fprintf(file, "%d,%.2lf\n",x,Branches[b].sales[x]);
//fprintf(file,"\n");
}
printf("\n\n");
}
//fclose(file);
printf("Branch\\Month:\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t11\t12\n");
for(int b=0; b<number_of_branches; b++)
{
printf("Branch %d:\t",(b+1));
for(int x=0;x<12;x++)
{
printf("%.2lf\t",(Branches[b].sales[x]));
}
printf("\n");
}
return 0;
Branch * Branchplace = (Branch *) malloc(sizeof(Branch));
}
double function_two(void)
{
Branch Branches[number_of_branches++];
printf("Sales for the new branch number %d\n",(number_of_branches));
for(int x=0;x<12;x++)
{
printf("Sales for month %d: ",(x+1));
scanf("%lf",&Branches[number_of_branches].sales[x]);
//printf("\n%d\n",x);
}
printf("\n");
printf("Branch\\Month:\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t11\t12\n");
for(int b=0; b<number_of_branches; b++)
{
printf("Branch %d:\t",(b+1));
for(int x=0;x<12;x++)
{
printf("%.2lf\t",(Branches[b].sales[x]));
//printf("\n%lf\n",Branches[b].sales[x]);
//fprintf(file, "%d,%lf",x,Branches[b].sales[x]);
}
printf("\n");
}
return 0;
}
double function_three(void)
{
Branch Branches[number_of_branches];
int deleted_branch;
printf("Which branch do you want to delete?\n");
scanf("%d",&deleted_branch);
Branches[deleted_branch].active=false;
printf("Deleted branch %d\n",deleted_branch);
return 0;
}
void function_four(void)
{
Branch Branches[number_of_branches];
for(int n=0;n<number_of_branches;n++)
{
for(int x=0;x<12;x++)
printf("%.lf\n",Branches[n].sales[x]);
}
}
it is easy to pass an array, no need for pointer
void myfunction(int array[]) {
/** your code here **/
array[0] = 25;
}
void main() {
int arr[] = {1, 2, 4, 5, 6};
int i;
myfunction(arr);
for(i=0;i<4;i++) {
printf("%d\n", arr[i]);
}
}
Output
25
2
4
5
As you can see the value 25 is printing which is actually modified inside the function

Read values into an array fails

I want to use a function to scanf up to 10 values for an array with the size 10, and also keep track of the number of values that are in the array because I'll need it later for solving some maths about the array, (max value, min value, etc.).
#include <stdio.h>
int enter(int MeasurmentData[], int nrOfmeasurments)
{
for(int i=0;i<10;++i)
{
int MeasurmentData[10];
scanf("%d",&MeasurmentData[i]);
int nrOfmeasurments = 0;
nrOfmeasurments ++;
return nrOfmeasurments;
}
int main()
{
int MeasurmentData[10];
int nrOfmeasurments;
char menuoption;
while (1)
{
printf("Measurment tool 2.0\n");
printf("v (View)\n");
printf("e (Enter)\n");
printf("c (Compute)\n");
printf("r (Reset)\n");
printf("q (Quit)\n");
printf("enter your option:\n");
scanf(" %c", &menuoption);
if (menuoption =='e') \\ enter values
{
int MeasurmentData[10];
int nrOfmeasurments;
enter(MeasurmentData, nrOfmeasurments);
}
else if(menuoption == 'v') \\\ view values
{
//printf("%d", MeasurmentData[]);
}
else if(menuoption == 'c')
{
}
if(menuoption == 'q')
{
printf("Exiting Measurment tool 2.0\n");
return 0;
}
}
}
When I run the program it should print Measurment tool 2.0, after the the user has the choice of inputting e(enter) which will scan in up to 10 values into an array, if the user clicks q(quit) while in the enter option already he will be returned to the main menu where he can do whatever.
V(view) prints out the array for the user so that he can view what elements are inside.
C(compute) uses the elements inside and the nr of elements to calculate the highest value element, lowest.
There are some errors in your code. Ill try to explain. You have over declared your variables too many times. And since you have a fixed loop you don't need to count the measurements you will always read 10 measurements.
Below are the code with some modifications. Feel free to ask anything about it.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXIMUM_MEASURMENT 10
int enter(int MeasurmentData[])
{
char input[100];
int nrMeasurement = 0;
// reseting Measurment data
for(int i=0;i<MAXIMUM_MEASURMENT;++i) MeasurmentData[i] = 0;
for(int i=0;i<MAXIMUM_MEASURMENT;++i)
{
scanf("%99s", input);
if(strcmp(input, "q") == 0) {
break;
}
MeasurmentData[i] = (int) strtol(input, (char **)NULL, 10);
nrMeasurement++;
}
return nrMeasurement;
}
void showMeasurments(int* MeasurmentData, int length) {
int i = 0;
printf(" ======== Measurment ======== \n");
for(i = 0; i < length; i++) {
printf("%d ", MeasurmentData[i]);
}
printf("\n");
}
int main()
{
int MeasurmentData[MAXIMUM_MEASURMENT];
int nrOfmeasurments;
char menuoption;
while (1)
{
printf("Measurment tool 2.0\n" "v (View)\n" "e (Enter)\n" "c (Compute)\n" "r (Reset)\n" "q (Quit)\n enter your option:\n");
scanf(" %c", &menuoption);
if (menuoption =='e') // enter values
{
enter(MeasurmentData);
}
else if(menuoption == 'v') // view values
{
// show
showMeasurments(MeasurmentData, MAXIMUM_MEASURMENT);
}
else if(menuoption == 'c')
{
}
if(menuoption == 'q')
{
printf("Exiting Measurment tool 2.0\n");
break;
}
}
return 0;
}
Edit: i have updated the code. So i have read the comments of your question and there you have explained a little better what you are trying to accomplish. So since you have the requirement to press 'q' to stop reading values. I have to read all measurments as string and convert to integer if it is not the character q.
Edit 2: Thanks to #user3629249 to point out some of the flaws from the code ill update with his suggestions.

Arithmetic and geometric average error solution

My code causes problems connected with giving the final result.
Earlier the program returned that there is an error in division by zero in geometric average. Now the program in arithmetic average returns -2.00000.
Program shows #IND00 error in SredniaGeometryczna(); — it is Geometric Average.
Do you have any idea how to solve it? Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
int ilosc(int*);
double sredniaArytmetyczna(int, int*);
double sredniaGeometryczna(int, int*);
double sredniaHarmoniczna(int, int*);
int main()
{
int tab[10];
char wybor;
printf("Wybierz, ktora srednia chcesz policzyc: [A]rytmetyczna, [G]eometryczna, [H]armoniczna.\n");
wybor=getch();
int ile;
long double srednia;
switch(wybor)
{
case 'a':
case 'A':
//instrukcje dla arytmetycznej
ile=ilosc(tab);
srednia=sredniaArytmetyczna(ile, tab);
printf("Srednia to: %f",srednia);
//tab* == tab[0]
//printf("Srednia to: %f", sredniaArytmetyczna(ilosc(tab),tab)); - mozna tak samo zrobic za pomoca jednej linijki
break;
case 'g':
case 'G':
//instrukcje dla geometrycznej
ile=ilosc(tab);
srednia=sredniaGeometryczna(ile, tab);
printf("Srednia to: %f",srednia);
break;
case 'h':
case 'H':
ile=ilosc(tab);
srednia=sredniaHarmoniczna(ile, tab);
printf("Srednia to: %f",srednia);
break;
default:
printf("Bledny wybor");
}
return 0;
}
int ilosc(int* tablica)
{
int ileLiczb, i;
printf("Podaj ile liczb chcesz wprowadzic (max 10) : \n");
scanf("%d", &ileLiczb);
i=0;
while(i<ileLiczb)
{
printf("Podaj %d liczbe calkowita: ", i+1);
scanf("%d", &tablica[i]);
++i;
}
return 0;
}
double sredniaArytmetyczna(int iloscLiczb, int *Tab)
{
double wynik=0;
for(int i=0; i<iloscLiczb; ++i)
{
wynik+=Tab[i];
}
return wynik/iloscLiczb;
}
double sredniaGeometryczna(int iloscLiczb, int *Tab)
{
double wynik=0;
for(int i=0; i<iloscLiczb; ++i)
{
wynik=Tab[i]*Tab[++i];
}
return pow(wynik,1/iloscLiczb);
}
double sredniaHarmoniczna(int iloscLiczb, int *Tab)
{
double wynik=0;
for(int i=0; i<iloscLiczb; ++i)
{
wynik+=(1/Tab[i]);
}
return iloscLiczb/wynik;
}
ilosc is supposed to return the count of numbers, but it always returns 0. Change
return 0;
to
return ileLiczb;
And when you're calculating the power in sredniaGeometryczna, you're performing integer arithmetic. You need to change 1/iloscLiczb to 1/(double)iloscLiczb so it will perform floating point arithmetic. Or you could change the declaration of the iloscLiczb parameter to double, and it will be converted automatically when the function is called.
You need a similar change in sredniaHarmoniczna. Change 1/Tab[i] to 1/(double)Tab[i]

Advance calculator for finding the mode of a set of numbers

I am currently working on a project for school in which I need to program a calculator to determine the mode of a set of numbers. The parameters are the numbers have to be between 1 and 30. Have to check whether the user inserts a number within that range and that the number must be validated as an integer. I have most of it done except my main issues are the for loop in inputing the numbers and validating them and making sure my mode function works. Any suggestions in fixing the issue with the loop? Also I must use a mode function in order to calculate the mode does the one I'm using work well or is there a better way in going about it?
#include <stdio.h>
#include <string.h>
#include <math.h>
int mode(int *num, int size);
int main(int n, char **p) {
int modearray[], size, i;
printf("What is the size of the Array?");
scanf("%d", &size);
for (i=0; i<modearray[size]; i++) {
printf("Enter an integer value (1 to 30): ");
scanf("%d", modearray[i]);
if (modearray[i] < 1 || modearray[i] > 30) {
printf("Please enter a value within the range");
scanf("%d", modearray[i])
}
else if (sscanf(p[i], "%i", &a[i]) != 1) {
printf("ERROR\n");
return -1;
}
}
}
//used the mode function code frome http://www.dreamincode.net/forums/topic/43713- pointers-and-modefunction/
int mode(int *num, int size) {
int currentnum = (*num);
int count = 0;
int modenum = -1;
int modecount = 1;
for (int x=0; x<size; x++) {
if (currentnum==(*num + x)) count ++;
else {
if(count > modecount) {
modenum = currentnum;
// modecount = count;
x--;
}
currentnum=*(num + x);
count = 0;
}
}
}
As Charlie and user2533527 have already indicated, there are errors in the OP code, and they have offered suggestions regarding those errors. There are a few others that I have noted in my edit of your original code below, that without addressing, the code did not build and/or run. So, if you are interested, look at the inline comments at the bottom of this post to see some corrections to your original code.
This answer is focused on validation of input, per your stated objective ( Have to check whether the user inserts a number within that range and that the number must be validated as an integer ) Specifically it appears you need to verify that the numbers input fall within a range, AND that they all be an integers.
If you move all of the validation steps into one function, such as:
int ValidateInput(char *num)
{
if(strstr(num, ".")!=NULL) return FLOAT;
if (atoi(num) < 1) return SMALL;
if (atoi(num) > 30) return LARGE;
return VALID;
}
then the main user input loop can be easily executed to include specific errors, if any, or continue with data collection by using a switch() statement, such as:
status = ValidateInput(number);
switch(status) {
case VALID:
modearray[i] = atoi(number);
printf("Enter an integer value %d: (1 to 30): ", i+2);
break;
case FLOAT:
printf("float detected, enter an integer");
i--;//try again
break;
case SMALL:
printf("value too small, enter value from 1 to 30");
i--;//try again
break;
case LARGE:
printf("value too large, enter value from 1 to 30");
i--;//try again
break;
default:
//do something else here
break;
}
Altogether, this approach does not use the mode function, rather replaces it with ValidateInput() which ensures only numbers that are integers, and within the stated range are included in the modearray varible.
EDIT to include searching for mode (highest occurring number within group)
My approach will do three things to get mode
sort the array,
walk through the sorted array tracking count of the matches along the way.
keep the highest string of matches.
To do this, I will use qsort() and looping in the mode() function.
int mode(int *num, int size) {
int count = 0;
int countKeep=0;
int modenum = -1;
qsort(num, size, sizeof(int), cmpfunc);
//now we have size in ascending order, get count of most occuring
for (int x=1; x<size; x++)
{
if(num[x-1] == num[x])
{
count++;
if(count > countKeep)
{
countKeep = count;
modenum=num[x];
}
else
{
count = 0;
}
}
}
return modenum;
}
Here is the complete code for my approach: (This code will capture the mode of a string of numbers with only one mode. You can modify the looping to determine if the string is multi-modal, or having two equally occuring numbers)
#include <ansi_c.h> //malloc
//#include <stdio.h>//I did not need these others, you might
//#include <string.h>
//#include <math.h>
int ValidateInput(char *num);
int mode(int *num, int size);
int cmpfunc (const void * a, const void * b);
enum {
VALID,
FLOAT,
SMALL,
LARGE
};
int main(int n, char **p)
{
int *modearray, size, i;
int *a;
char number[10];
int status=-1;
int modeOfArray;
printf("What is the size of the Array?");
scanf("%d", &size);
modearray = malloc(size*sizeof(int));
a = malloc(size);
printf("Enter an integer value 1: (1 to 30): ");
for (i=0; i<size; i++)
{
scanf("%s", number);
//Validate Number:
status = ValidateInput(number);
switch(status) {
case VALID:
modearray[i] = atoi(number);
printf("Enter an integer value %d: (1 to 30): ", i+2);
break;
case FLOAT:
printf("float detected, enter an integer");
i--;//try again
break;
case SMALL:
printf("value too small, enter value from 1 to 30");
i--;//try again
break;
case LARGE:
printf("value too large, enter value from 1 to 30");
i--;//try again
break;
default:
//do something else here
break;
}
}
modeOfArray = mode(modearray, size);
getchar();//to view printf before execution exits
}
int ValidateInput(char *num)
{
if(strstr(num, ".")!=NULL) return FLOAT;
if (atoi(num) < 1) return SMALL;
if (atoi(num) > 30) return LARGE;
return VALID;
}
int mode(int *num, int size) {
int count = 0;
int countKeep=0;
int modenum = -1;
qsort(num, size, sizeof(int), cmpfunc);
//now we have size in ascending order, get count of most occuring
for (int x=1; x<size; x++)
{
if(num[x-1] == num[x])
{
count++;
if(count > countKeep)
{
countKeep = count;
modenum=num[x];
}
else
{
count = 0;
}
}
}
return modenum;
}
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
Assuming that the question is about crashing after the scanf in to array:
int main(int n, char **p) {
int *modearray, size, i;
printf("What is the size of the Array?");
scanf("%d", &size);
modearray = malloc(size * sizeof(int)); //imo size of int is 4 so u can replace with
for (i=0; i<modearray[size]; i++) {
printf("Enter an integer value (1 to 30): ");
scanf("%d", modearray[i]);
if (modearray[i] < 1 || modearray[i] > 30) {
printf("Please enter a value within the range");
scanf("%d", &modearray[i])
}
else if (sscanf(p[i], "%i", &a[i]) != 1) {
printf("ERROR\n");
return -1;
}
}
}

Segmentation fault with no pointers?

Here is my code and problem. The code compiles fine. But when I run it. After I enter the menu option in getMenuOption() "Segmentation Fault (core dumped)" pops up. What is wrong?
I'm new to programming in general. Thanks for the help if its provided.
#include <stdio.h>
#include<math.h>
#define CALCULATE_PI 'a'
#define CALCULATE_GEOMEAN 'b'
#define CALCULATE_HARMMEAN 'c'
void printInstructions (void);
void printMenuOptions (void);
int runMenuOption ();
int getMenuOption ();
int getLimit ();
int calculatePi ();
int calculateGeoMean ();
int calculateHarmonicMean ();
int main(void)
{
printInstructions();
printMenuOptions();
runMenuOption(getMenuOption());
return 0;
}
void printInstructions (void)
{
printf("======================================================\n");
printf("= PI, Geometric Mean, and Harmonic Mean Calculator =\n");
printf("= Please refer to the menu to choose calucaltion =\n");
printf("=Choose desired menu option and press enter to begin =\n");
printf("= Proceed to follow on-screen instructions =\n");
printf("======================================================\n\n\n");
return;
}
void printMenuOptions (void)
{
printf("3 choices: Please enter a VALID letter.\n");
printf("Choice 'a' = Calcualtes PI\n");
printf("Choice 'b' = Calculates Geometric Mean\n");
printf("Choice 'c' = Calculates Harmonic Mean\n\n");
return;
}
int runMenuOption (int getMenuOption())
{
char option;
double answer,
Pi = 0.0,
geoMean = 0.0;
option = getMenuOption();
switch (option)
{
case CALCULATE_PI:
calculatePi(getLimit());
answer = Pi;
break;
case CALCULATE_GEOMEAN:
calculateGeoMean(getLimit());
answer = geoMean;
case CALCULATE_HARMMEAN:
printf("Harmonic Mean");
break;
default:
printf("Incorrect Character!\n");
printf("Try again");
break;
}
printf("Your answer is %5p", &answer);
return 0;
}
int getMenuOption (void)
{
char option;
printf("Please enter choice: ");
scanf("%c", &option);
return option;
}
int getLimit ()
{
int limit;
scanf("%d", &limit);
return limit;
}
int calculatePi (void)
{
int limit,
count = 0,
Pi = 0;
printf("Please enter the PI limit: ");
limit = getLimit();
for (count = 1; count <= limit; count++)
{
Pi += 1 / count;
}
return sqrt(Pi * 6);
}
int calculateGeoMean()
{
int limit,
userValue = 0,
count = 0;
double geoMean = 0;
limit = getLimit();
while(count <= limit)
{
if (userValue <= 0)
printf("Incorrect. Try again");
else
{
count++;
userValue *= userValue;
}
}
geoMean = userValue;
return sqrt(userValue);
}
int calculateHarmonicMean()
{
int limit,
userValue = 0,
count = 0;
double harmMean = 0;
limit = getLimit();
while(count <= limit)
{
if (userValue <= 0)
printf("Incorrect. Try again");
else
{
count++;
userValue *= 1 / userValue;
}
}
harmMean = userValue;
return limit / userValue;
}
This function definition is totally wrong.
int runMenuOption (int getMenuOption())
either you can pass the return value of getMenuOption like this
int runMenuOption (int option)
or
you shouldn't pass any value to this function and call getMenuOption inside runMenuOption. You are doing both, which is incorrect.
int runMenuOption (int getMenuOption())
Here's your problem.
That should be:
int runMenuOption (int opt)
Also, you shouldn't be calling getMenuOption() within runMenuOption since you're calling getMenuOption() as you pass it to runMenuOption as a parameter. runMenuOption should only have a switch statement.
You need to modify the definition of your function from int runMenuOption (int getMenuOption()) to int runMenuOption (int option). In the call, getMenuOption() will be invoked and the output placed into the stack frame of the called function.
According to your declaration of the runMenuOption function, it takes a pointer to a function which returns an integer as its first argument:
int runMenuOption (int getMenuOption())
The function is then called in this line:
option = getMenuOption();
This is perfectly fine. However, the problem lies in this line:
runMenuOption(getMenuOption());
Here you are calling the getMenuOption function and passing the return value into the runMenuOption function. But what you should be doing is passing the function itself as the argument:
runMenuOption(getMenuOption);
The reason you are getting a Segmentation Fault error is because the return value from the getMenuOption function is being treated as a function pointer, and your program is attempting to call a function at that address, which is of course invalid.

Resources