I'm having an issue with my menu. I get a number from the user but whenever I get a number it just does option one no matter what I do. What am I doing wrong?
int main()
{
int array[SIZE];
int size = readNum();
fillArray(array, size);
char option = 'y';
do
{
int num = menu();
if(num == 1)
fillArray(array, size);
else if(num == 2)
{
int newSize = readNum();
fillArray(array, newSize);
}
else
{
sortArray(array);
}
}while(option == 'y');
return 0;
}//end main
int menu()
{
printf("1)Change the values of the array\n2)Change the size of the array and the values in the array\n3)Find and display the mean and median\nChoice: ");
int menuChoice = scanf("%i", &menuChoice);
return menuChoice;
}
The scanf function returns the number or successful conversion it made, not the actual converted value. It seems it always succeeding in reading you value, so will return 1 for one successful conversion.
To return the actual user choice, do not assign to it from the call:
int menuChoice:
scanf("%i", &menuChoice);
return menuChoice;
int menuChoice = scanf("%i", &menuChoice);
scanf returns the number of successful conversions, so if the scan succeeds, you are overwriting the converted value with 1.
Related
the question is "write a recursive function that ends when -1 is entered, than return how many times an even number was scanned.
naturals(int);
static void main() {
int num;
printf("enter numbers\n");
scanf("%d", &num);
naturals(num);
}
naturals(int num) {
int count = 0;
if (num % 2 == 0) {
count++;
}
if (num == -1) {
printf("%d", count);
return 0;
}
scanf("%d", &num);
return naturals(num);
}
i know that it resets "count" to 0 at the start of the function, how do i solve this?
This is a good place to make use of the ?: operator:
#include <stdio.h>
int naturals(int count)
{
int num;
scanf("%d", &num);
return num == -1 ? count : naturals(num % 2 == 0 ? count+1 : count);
}
int main(int argc, char **argv)
{
printf("enter numbers\n");
printf("even numbers entered = %d\n", naturals(0));
}
Here I'm passing 0 in as the initial count in the call to naturals in main, then for each number entered count is incremented if the number is even; otherwise we just pass the unincremented count to the next invocation of naturals. Prior to making the recursive call to naturals we check to see if the number entered is -1; if it is we return the current value of count, otherwise we proceed to make a recursive call to naturals.
If you prefer, the return line in naturals can be replaced with
if(num == -1)
return count;
else if(num % 2 == 0)
return naturals(count+1);
else
return naturals(count);
which is functionally the same. It has the disadvantage of having three separate return statements which IMO is more confusing, but YMMV.
You can't keep track of count inside your recursive function. As you have correctly observed, count is reset to 0 every time the function runs. Instead, you'll have to keep track of count outside of your function. Here are some ways of doing this:
Pass count as a parameter to your recursive function, update it, and have your recursive function return the new value;
Create a global variable count and update is as necessary every time the recursive function runs.
#include <stdio.h>
#include <math.h>l
naturals(int, int);
static void main() {
int num, count = 0;
printf("enter numbers\n");
scanf("%d", &num);
naturals(num, count);
}
naturals(int num, int count) {
if (num % 2 == 0) {
count += 1;
}
if (num == -1) {
printf("%d\n", count);
return 0;
}
scanf("%d", &num);
return naturals(num, count);
}
solved it thanks!
#include <stdio.h>
#include <stdlib.h>
int add_even(int);
int add_odd(int);
int main() {
int num, result_odd, result_even, even_count, odd_count;
char name;
printf("What is your name?\n");
scanf("%s", &name);
while (num != 0) {
printf("Enter a number:\n");
scanf("%d", &num);
if (num % 2 == 1) {
printf ("odd\n");
odd_count++;
} else
if (num == 0) {
printf("%s, the numbers you have entered are broken down as follows:\n",
name);
result_even = add_even(num);
printf("You entered %d even numbers with a total value of %d\n",
even_count, result_even);
result_odd = add_odd(num);
printf("You entered %d odd numbers with a total value of %d\n",
odd_count, result_odd);
} else {
printf("even\n");
even_count++;
}
}
return 0;
}
int add_even(int num) {
static int sum = 0;
if (num % 2 != 0) {
return 0;
}
sum += add_even(num);
return sum;
}
int add_odd(int num) {
static int sum = 0;
if (num % 2 == 0) {
return 0;
}
sum += add_odd(num);
return sum;
}
Can anyone give me some insight as to what I did wrong exactly?
The point of the code is to get inputs from the user until they decide to stop by inputting 0. Separating the evens from the odd. Tell them how many even/odd they put and the total of all the even/odd numbers.
I understand how to separate the evens from the odds. I think my issue is with my function.
There are multiple problems in your code:
scanf() causes undefined behavior when trying to store a string into a single character. Pass an array and specify a maximum length.
you should check the return value of scanf(): if scanf() fails to convert the input according to the specification, the values are unmodified, thus uninitialized, and undefined behavior ensues. In your case, if 2 or more words are typed at the prompt for the name, scanf("%d",...) fails because non numeric input is pending, no further characters are read from stdin and num is not set.
num is uninitialized in the first while (num != 0), causing undefined behavior.
functions add_even() and add_odd() are only called for num == 0, never summing anything.
functions add_even() and add_odd() should always return the sum and add the value of the argument num is it has the correct parity. They currently cause undefined behavior by calling themselves recursively indefinitely.
odd_count and even_count are uninitialized, so the counts would be indeterminate and reading their invokes undefined behavior.
In spite of all the sources of undefined behavior mentioned above, the reason your program keeps prompting without expecting an answer if probably that you type more than one word for the name. Only a single word is converted for %s, leaving the rest as input for numbers, which repeatedly fails in the loop. These failures go unnoticed as you do not verify the return value of scanf().
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
int add_even(int);
int add_odd(int);
int main(void) {
int num, result_odd, result_even, even_count = 0, odd_count = 0;
char name[100];
printf("What is your name? ");
if (scanf("%99[^\n]", name) != 1)
return 1;
for (;;) {
printf("Enter a number: ");
if (scanf("%d", &num) != 1 || num == 0)
break;
if (num % 2 == 1) {
printf("odd\n");
odd_count++;
add_odd(num);
} else {
printf("even\n");
even_count++;
add_even(num);
}
printf("%s, the numbers you have entered are broken down as follows:\n", name);
result_even = add_even(0);
printf("You entered %d even numbers with a total value of %d\n",
even_count, result_even);
result_odd = add_odd(0);
printf("You entered %d odd numbers with a total value of %d\n",
odd_count, result_odd);
}
return 0;
}
int add_even(int num) {
static int sum = 0;
if (num % 2 == 0) {
sum += num;
}
return sum;
}
int add_odd(int num) {
static int sum = 0;
if (num % 2 != 0) {
sum += num;
}
return sum;
}
You declared:
char name; // One single letter, such as 'A', or 'M'
printf("What is your name?\n"); // Please enter a whole bunch of letters!
scanf("%s", &name); // Not enough space to store the response!
What you really want is more like
char name[31]; // Up to 30 letters, and an End-of-String marker
printf("What is your name?\n"); // Please enter a whole bunch of letters!
scanf("%s", name); // name is the location to put all those letters
// (but not more than 30!)
I'm trying to create a program in which the user enters three integers, and another function checks to see that their input is valid. If the input is not valid, then the user must input three new numbers.
#include <stdio.h>
int sanitizedInput(int a, int b, int c)
{
if(scanf("%d", &a)==0)
{
printf("Not a number\n");
return 1;
}
else if(scanf("%d", &b)==0)
{
printf("Not a number\n");
return 1;
}
else if(scanf("%d", &c) == 0)
{
printf("Not a number\n");
return 1;
}
else
return 0;
}
int main()
{
int a;
int b;
int c;
int check = 1;
do
{
check = 0;
printf("Enter a number:");
scanf("%d",&a);
printf("Enter a number:");
scanf("%d",&b);
printf("Enter a number:");
scanf("%d",&c);
check = sanitizedInput(a,b,c);
}while(check);
}
However when I run this code, after entering three valid integers nothing shows up in the terminal and the code only terminates after entering 6 integers. (There are other functions and code in the main function, if that code is necessary to find the problem tell me and I will post it.)
Your code and your writing part is not matching.....
You should check the three numbers are valid or not firstly.
int sanitizedInput(int a, int b, int c)
{
if(a==0 || b==0 || c==0)
{
return 1;
}
else
{
printf("They are valid.....\n");
return 0;
}
}
Then if one of them are invalid, you will be able to take another three input for the returning value of 1. Because while(1) is a true condition.
remove
printf("Enter a number:");
scanf("%d",&a);
printf("Enter a number:");
scanf("%d",&b);
printf("Enter a number:");
scanf("%d",&c);
and stay with check = sanitizedInput(a,b,c);, and add printf("something\n") to the
else
return 0; block
and see what happens
In main() you are taking input for three numbers a,b,c and passing these variables as arguments for sanitizedInput().
Here, instead of checking the variables you are again using scanf() which will take new input.
if(scanf("%d", &a)==0)
The above if condition will not check the value of 'a', it will check the return value of scanf() with '0'.
if statement should be like this
if(a==0)
scanf("%d",&a);
this is same for all three variables.
In main function you are passing variables to sanitizedInput(), there you are checking variables and if not valid you are taking input again, so the variable which you changed are local to that function, which will not reflect in main(). So take care about that.
Hope this will help you.
In your while loop,you actually call scanf twice each variable(a,b,c),so you input number for 6 times.When sanitizedInput(a,b,c) finished,it return 0;so check is 0,the loop is over.I think you can do with in your main:
int main
{
int a;
int b;
int c;
int check = 0;
do
{
check = sanitizedInput(a,b,c);
printf("check = %d\n",check);
}while(!check);
return 0;
}
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;
}
}
}
I've already asked on here in another post, but none of the answers helped my program. I have a program that asks the user for numbers and calculates the mean, median, and mode. Then the program should prompt the user to play again, and if the user selects y or Y it should replay the game, n or N to stop, and if something else other than that, say invalid and please type y or n to bla bla you get it. here is my main, and my method goAgain() :
#define MAX 25
#include<stdio.h>
#include <stdbool.h>
#include <time.h>
#include <stdlib.h>
int readTotalNums();
void fillArray(int total, int nums[]);
void sortArray(int nums[], int total);
double findMean(int nums[], int total);
double findMedian(int nums[], int total);
int findMode(int nums[], int total);
void printResults(double mean, double median, double mode);
bool goAgain();
int main() {
int nums[MAX];
int total;
double mean, median, mode;
bool b;
do {
total = readTotalNums();
fillArray(total, nums);
sortArray(nums, total);
mean = findMean(nums, total);
median = findMedian(nums, total);
mode = findMode(nums, total);
printResults(mean, median, mode);
b = goAgain();
} while (b==true);
return 0;
}
//other methods here
bool goAgain() {
char *temp;
printf("\nWould you like to play again(Y/N)? ");
scanf("%c", &temp);
while (temp != 'n' && temp != 'N' && temp != 'y' && temp != 'Y') {
printf("\nI am sorry that is invalid -- try again");
printf("\nWould you like to play again(Y/N)? ");
scanf("%c", &temp);
}
if (temp == 'y' || temp == 'Y') {
return true;
} else {
return false;
}
}
every time I play the game, and it gets to the prompt, anything I type it just does nothing, and keeps saying invalid try again, even if the input is a y or N. thanks for your help :)
char *temp; should be char temp;
Don't declare temp as a pointer, also you have not allocated memory for it.
Instead change your declaration to
char temp;
since you already have the right answer, no need to say that again, so I'll add a small tip.
//this
if (temp == 'y' || temp == 'Y') {
return true;
} else {
return false;
}
//is the same as this
return temp == 'y' || temp == 'Y';
//or more generally
if(condition)
return true
else
return false
//is just
return condition