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.
Related
I have this silly program with my silly problem. I am a very beginner. Let me tell you what I want to do and what is happening here:
What I want to do: I am basically trying to make a function for input which is named here as inp(). This function will ask for input using these two lines:
printf("Enter the Number: ");
scanf("%d", &dip);
When my program will get the number from the user, it will store that inside a variable, let's say dip and will use this number in our another two functions named squarefn and cubefn. I don't know what's going wrong here. But, I can't use the inp() properly to get the number from user.
Why I want to use the inp() function?: Basically, I just want to keep everything inside each function so whenever I need, I will just call my functions. I created inp() so that, I don't need to ask twice or type twice for input.
**What is the output?: ** It's showing some random value or trash value.
Need more information? Feel free to ask!
#include<stdio.h>
int squarefn(int x);
int cubefn(int cube);
int coic();
int printkor(int printkortesi);
int inp();
int main()
{
coic();
}
int squarefn(int input)
{
input = input * input;
return input;
}
int cubefn(int input)
{
input = input * input * input;
return input;
}
int coic()
{
int coi;
int x;
printf("Which one you want?\n");
printf("1. Square\n");
printf("2. Cube\n");
printf("Enter here: ");
scanf("%d", &coi);
int cubed = cubefn(x);
switch (coi)
{
case 1:
// printf("Enter the Number: ");
// scanf("%d", &x);
inp();
int dear = inp(x);
squarefn(dear);
int squared = squarefn(x);
printkor(squared);
break;
case 2:
printf("Enter the Number: ");
scanf("%d", &x);
cubefn(x);
int cubed = cubefn(x);
printkor(cubed);
break;
default:
printf("Error.");
break;
}
}
int inp()
{
int dip;
printf("Enter the Number: ");
scanf("%d", &dip);
return dip;
}
int printkor(int printkortesi)
{
printf("Printed: %d", printkortesi);
}
There is a lot of redundant code in your program, many of the statements don't do anything except taking CPU time . Read about Function Calls in C. Most of your doubts will be solved after a good read
return_type function_name( parameter list ) {
body of the function
}
You have return type of int, to receive value of function foo
int foo(int x)
{return x*x;}
int main()
{
int y =foo(5); //integer y takes value returned by function foo, that is 5
printf("%d\n",y); // This will print value 25
return 0;
}
Your code altered as below, should work now:
#include<stdio.h>
int squarefn(int x);
int cubefn(int cube);
int coic();
int printkor(int printkortesi);
int inp();
int main()
{
coic();
}
int squarefn(int input)
{
input = input * input;
return input;
}
int cubefn(int input)
{
input = input * input * input;
return input;
}
int coic()
{
int coi;
int x;
printf("Which one you want?\n");
printf("1. Square\n");
printf("2. Cube\n");
printf("Enter here: ");
scanf("%d", &coi);
int cubed = cubefn(x);
int dear = inp();
switch (coi)
{
case 1:
{int squared = squarefn(dear);
printkor(squared);
break;}
case 2:
{int cubed = cubefn(dear);
printkor(cubed);
break;}
default:
printf("Error.");
break;
}
}
int inp()
{
int dip;
printf("Enter the Number: ");
scanf("%d", &dip);
return dip;
}
int printkor(int printkortesi)
{
printf("Printed: %d\n", printkortesi);
}
Edit:
Fixed it, I just noticed there was variable declaration in the switch statement. Case statements are only labels. This means the compiler will interpret this as a jump directly to the label. So I added { } in switch and it should work now.
With the code below, I'd always run into "Stack around the variable 'UserCode' was corrupted.
If I'm not mistaken, when I do userCode = (char*)malloc(sizeof(char)*N);, shouldn't it create an "array" with size of char*n ? I'm guessing my issue is either with my declaration of an array, or my pointer arithmetic.
Any help would be highly appreciated.
#include "stdafx.h"
#include <math.h>
int userPrompt1() {
int numOfAlphabets = 0;
printf("Please enter a number from 1 to 8 to choose how many alphabets you want\n");
scanf_s(" %d", &numOfAlphabets);
if (numOfAlphabets > 8 || numOfAlphabets < 0) {
printf("Sorry! Invalid number entered. Try again. \n");
numOfAlphabets = userPrompt1();
}
return numOfAlphabets;
}
int userPrompt2() {
int numOfLetters = 0;
printf("Please enter the number of letters you want to guess\n");
scanf_s(" %d", &numOfLetters);
if (numOfLetters < 0) {
printf("Sorry! Invalid number entered. Try again. \n");
numOfLetters = userPrompt2;
}
return numOfLetters;
}
int tryCalculator(int K, int N) {
int tries = 0;
tries = 1 + ceil(N * log2(K));
return tries;
}
void codeGenerator(char codeGuessIn[], char letters[], int size) {
for (int i = 0; i < size; i++) {
int rando = rand() % size;
codeGuessIn[i] = letters[rando];
printf(" %c", codeGuessIn[i]);
}
printf("\n");
}
void codeChecker(char codeGuessIn[], char generatedCode[], int size) {
int correctAlphabets = 0;
for (int i = 0; i < size; i++) {
if (codeGuessIn[i] == generatedCode[i]) {
correctAlphabets++;
}
}
printf(" %d in correct place \n", correctAlphabets);
}
void getUserCode(int size, char *userCode[]) {
for (int i = 0; i < size; i++) {
printf("Please enter letter #%d \n", i+1);
getchar();
scanf_s(" %c", &userCode[i]);
}
}
int main(void)
{
char letters[8] = { 'A','B','C','D','E','F','G','H' };
char *generatedCode; //array to hold generated code
char *userCode; // array to hold generated code.
int K = userPrompt1(); //how many different alphabets in code
int N = userPrompt2(); //how many letters in code
int tries = tryCalculator(K, N);
//int gameEnd = 1;
userCode = (char*)malloc(sizeof(char)*N);
generatedCode = (char*)malloc(sizeof(char)*N);
codeGenerator(generatedCode, letters, N);
getUserCode(N, &userCode);
//codeChecker(userCode, generatedCode, N);
return 0;
}
void getUserCode(int size, char *userCode[]) {
scanf_s(" %c", &userCode[i]);
Here, userCode[i] is a char * (pointer-to-char), &userCode[i] is a char ** (pointer-to-pointer-to-char), and scanf("%c") expects a char *. A good compiler would warn about that.
I think what you meant to do here is something like:
void getUserCode(int size, char *userCode) {
scanf_s(" %c", &userCode[i]);
}
int main(void) {
char *userCode = malloc(N);
getUserCode(N, userCode);
}
The printf(), getchar(), scanf() combination here reeks of the bad habits created by scanf: you're discarding the first character entered by the user because you're relying on an extra character in the input buffer.
See http://c-faq.com/stdio/scanfprobs.html and read full lines of input with fgets() instead of using scanf().
Also,
int userPrompt2() {
int numOfLetters = 0;
...
numOfLetters = userPrompt2;
}
You're assigning a function pointer to an int. (A normal compiler should warn about this.) If the idea here is to call the function again to repeat the prompt in case the user enters something silly, it's probably a better idea to use a loop instead of a recursive call anyway.
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);
I'm trying to write a program in C that finds prime numbers and calls a function. However I keep getting a singular error that says the called object 'is_prime' is not a function in line 22. I set up a prototype but it still doesn't work. Help!
#include<stdio.h>
double is_prime(int x);
int main()
{
double is_prime;
double primenum = 0;
int n=0;
int x=0;
printf("Enter the value of n: "); //getting length//
scanf("%d",&n);
printf("\n Printing primes less than or equal to %d: \n", n); //message//
for(x = 2; x <= n; x++) //loop to check and print prime #s//
{
primenum = is_prime(x); <------------line 22
if (primenum == 1)
{ printf("%d, ",x); }
}
return 0;
}
double is_prime(int x)
{
int i=0;
for (i = 2; i < x; i++) // this is the loop to check all numbers//
// under n to see if prime//
{
if (x==2)
{ return 1;}
if ((x%i) == 0)
{return 1;}
else
{return 0;}
}
}
You have declared a variable with the same name as the function:
double is_prime;
This shadows the name of the function from the point of the declaration to the end of the scope of main.
Use a different name for either, or remove the declaration above, since you don't seem to need it.
You define double is_prime;, so is_prime becomes a double, not a function.
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;
}
}
}