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
Related
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.
This is GA for a timetable problem. I'm trying to create an initial population, but it isn't working as it isn't entering the if condition. can someone point out the error?
I tried inserting statements in each condition, but everything checks out. Still, I don't seem to find a solution.
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
int random_number_creator(int upper, int lower)
{
int n;
n = rand() % (upper-lower)+ lower;
return n;
}
struct pop{
int subjects[6];
int days[5][9];
}oldpop, bench;
main()
{
int i,j,s=1,d,h,stop=1,cou=0;
for(i=0;i<5;i++)
{
for(j=0;j<9;j++)
if(j!=6)
bench.days[i][j]=0;
else
bench.days[i][j]=11111;
}
for(i=0;i<6;i++)
{
if(i<4)
oldpop.subjects[i]=3;
else
oldpop.subjects[i]=2;
}
for(i=0;i<5;i++)
{
printf("\n");
for(j=0;j<9;j++)
printf(" %d",bench.days[i][j]);
}
for(i=0;i<6;i++)
{
printf(" \n %d",oldpop.subjects[i]);
}
cou=0;
for(i=0;i<6;i++)
{
cou=cou+ oldpop.subjects[i];
}
printf("\n%d\n",cou);
do
{
s=random_number_creator(5,0);
printf("\nsubject number:%d\n",s);
printf("\nloop 1 entery %d",cou);
do
{
printf("\nloop 2 entry\n");
d=random_number_creator(5,0);h=random_number_creator(8,0);
printf("\nDay Number:%d \nHour Number:%d\n",d,h);
if(bench.days[d][h]==0&&oldpop.subjects[s]!=0)
{
printf("\nif condition reached\n");
oldpop.days[d][h]=10+s;
bench.days[d][h]=11111;
stop=0;
cou--;
oldpop.subjects[s]--;
}
else
{
printf("\nIf condition not satisified.\n");
break;
}
}while(stop!=0);
}while(cou!=0);
for(i=0;i<5;i++)
{
printf("final entery \n");
for(j=0;j<9;j++)
printf(" %d",oldpop.days[i][j]);
}
}
I want the oldpop variable to be initialized for this timetable problem but the code does not enter the if condition in the do while loop.
The problem in your program comes from the subject selection (after adding the missing }):
s=random_number_creator(5,0);
Will return a random number between 0 and 4 included.
To correct this, just replace this line by
s=random_number_creator(7,0);
To pick a number between 0 and 6. So the cou variable will be able to reach 0
Your code can be improved:
Instead of this kind of block:
for(i=0;i<5;i++)
{
printf("final entery \n");
for(j=0;j<9;j++)
printf(" %d",oldpop.days[i][j]);
}
Create a function, learn to use printf:
void print_table(struct pop pop, const char *label)
{
int i, j;
printf("\n%s\n", label);
for (i=0;i<5;i++)
{
for (j=0;j<9;j++)
{
printf(" %5d",pop.days[i][j]);
}
}
}
And use it this way
print_table(oldpop, "oldpop");
I'm new to programming so I'm trying to write a small program were I can show car information but also add cars to my "library"
right now my out come for 1.Show cars looks like this:
ID BRAND PICS
bbb188 BMW 1 2 3
AAA-999 VOLVO 4 5 6
CCC-999 CITROEN 1 2 3
but after I add a new car the PICS does not show.
so if I would add AAA-111 VOLVO 1. this is the outcome:
bbb188 BMW 1 2 3
AAA-999 VOLVO 4 5 6
CCC-999 CITROEN 1 2 3
AAA-111 VOLVO -398253632 3 3
I just get random numbers for pics and always 3 values.
Could anyone help me with this, and please show me how to do it instead.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX 1000
#define IDSIZE 20
#define BRANDSIZE 50
#define PICSIZE 10
typedef struct{
char id[IDSIZE+1];
char brand[BRANDSIZE+1];
int *pic;
} Car;
void printCar(Car *pCar,int imagecount)
{
printf(" %s ",pCar->id);
printf(" %s ",pCar->brand);
for(int i=0; i<imagecount; i++){
printf(" %d",pCar->pic[i]);
}
printf("\n");
}
Car initCar(char itsId[],char itsBrand[],int *itsPic, int imagecount)
{
Car newCar;
strcpy(newCar.id, itsId);
strcpy(newCar.brand, itsBrand);
newCar.pic = itsPic;
return newCar;
}
void PrintList(Car aLista[],int imagecount, int carcount)
{
for(int i = 0; i<imagecount; i++)
printCar(&aLista[i],carcount);
}
void AddCar(Car aList[], int *pAt, Car theCar)
{
aList[(*pAt)++]=theCar;
}
Car NewCar(Car minapatienter[], int patientCount)
{
Car newCar;
gets(newCar.id);
printf("type in ID \n");
gets(newCar.id);
printf("type in brand\n");
gets(newCar.brand);
bool imageInputDone = false;
int imageCount=0;
while(imageInputDone == false)
{
printf("type in image reference \n");
int newImage;
scanf("%d",&newImage);
newCar.pic = &newImage;
imageCount++;
printf("vill du \n1.Add another image reference \n2.exit\n");
int input;
scanf("%d", &input);
printf("input: %i\n",input);
switch(input)
{
case 1:
printf("Adding one more image\n");
break;
case 2:
printf("Leaving loop\n");
imageInputDone = true;
break;
default:
while (input<1 || input<2)
;
printf("Input correct number\n");
break;
}
return newCar;
}
}
int main(void)
{
int carCount=0;
int imagecount=0;
Car myCar[MAX];
int input;
int test[3]={1,2,3};
int test2[3]={4,5,6};
myCar[0]= initCar("bbb188","BMW", test, 3);
myCar[1] = initCar("AAA-999","VOLVO", test2, 3);
myCar[2] = initCar("CCC-999", "CITROEN", test,3);
carCount=3;
imagecount=3;
do {
printf("1. Show cars \n2. Add car \n");
scanf("%d",&input);
switch(input)
{
case 1:
printf("ID BRAND PICS \n");
PrintList(myCar,carCount, imagecount);
break;
case 2:
AddCar(myCar,&carCount,NewCar(myCar,carCount));
printf("ID BRAND PICS \n");
PrintList(myCar,carCount, imagecount);
} //break;
} while (input < '1'|| input < '2');
return 0;
}
Your NewCar function have some problems. The newImage is in stack memory. When you do assignment newCar.pic = &newImage; the newCar.pic will point to undefined memory region because newImage was out of its scope. better way, we just use its value only, don't use address operator here. And one more thing, the newCar.pic is an pointer (array of int). So you need to allocate it before use. When you add more image item, you need to reallocate it. And initialize the pic to NULL pointer as well.
Here is my modification your NewCar function:
Car NewCar(Car minapatienter[], int patientCount)
{
Car newCar;
gets(newCar.id);
printf("type in ID \n");
gets(newCar.id);
printf("type in brand\n");
gets(newCar.brand);
newCar.pic = NULL;
bool imageInputDone = false;
int imageCount=0;
while(imageInputDone == false)
{
printf("type in image reference \n");
int newImage;
scanf("%d",&newImage);
// Rellocation
newCar.pic = realloc(newCar.pic, (imageCount+1)*sizeof(int));
newCar.pic[imageCount] = newImage;
imageCount++;
printf("vill du \n1.Add another image reference \n2.exit\n");
int input;
scanf("%d", &input);
printf("input: %i\n",input);
switch(input)
{
case 1:
printf("Adding one more image\n");
break;
case 2:
printf("Leaving loop\n");
imageInputDone = true;
break;
default:
while (input<1 || input<2)
;
printf("Input correct number\n");
break;
}
return newCar;
}
}
You get the same number of images printed for each car because you only have a global counter. You need a counter per image:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX 1000
#define IDSIZE 20
#define BRANDSIZE 50
#define PICSIZE 10
typedef struct Car
{
char id[IDSIZE+1];
char brand[BRANDSIZE+1];
int *pic;
int imagecount;
} Car;
With this change there is no need to pass a count for printing:
void printCar(Car *pCar)
{
printf(" %s ", pCar->id);
printf(" %s ", pCar->brand);
for(int i=0; i<pCar->imagecount; i++)
{
printf(" %d",pCar->pic[i]);
}
printf("\n");
}
The counter needs to be stored during initialization:
Car initCar(char itsId[], char itsBrand[], int *itsPic, int imagecount)
{
Car newCar;
strcpy(newCar.id, itsId);
strcpy(newCar.brand, itsBrand);
newCar.pic = itsPic;
newCar.imagecount = imagecount;
return newCar;
}
When you print your list, you mix up count of images and count of cars:
void PrintList(Car aLista[], int imagecount, int carcount)
{
for(int i = 0; i<imagecount; i++)
printCar(&aLista[i],carcount);
}
This must be:
void PrintList(Car aLista[], int carcount)
{
for (int i = 0; i < carcount; i++)
printCar(&aLista[i]);
}
Adding the car to your array is basically OK, but you might check if you reach MAX cars.
void AddCar(Car aList[], int *pAt, Car theCar)
{
aList[(*pAt)++]=theCar;
}
Now the biggest problem. This function hads issues with memory usage and weird loops.
Car NewCar(void)
{
Car newCar = {0}; // initialze with empty strings and NULL pointers.
// TODO: Replace gets with fgets!
// gets(newCar.id); // WHY read before you prompt??
printf("type in ID \n");
gets(newCar.id);
printf("type in brand\n");
gets(newCar.brand);
bool imageInputDone = false;
int imageCount=0;
while(imageInputDone == false)
{
printf("type in image reference \n");
int newImage;
scanf("%d",&newImage);
imageCount++;
int *newpics = realloc(newCar.pic, (imageCount) * sizeof(int));
newpics[imageCount-1] = newImage;
newCar.pic = newpics;
// TODO: Check for NULL
printf("vill du \n1.Add another image reference \n2.exit\n");
int input;
scanf("%d", &input);
printf("input: %i\n",input);
while (input < 1 || input > 2)
switch(input)
{
case 1:
printf("Adding one more image\n");
break;
case 2:
printf("Leaving loop\n");
imageInputDone = true;
break;
default:
printf("Input correct number\n");
break;
}
newCar.imagecount = imageCount;
return newCar;
}
}
And finally...
int main(void)
{
int carCount=0;
Car myCar[MAX];
int input;
int test[3] = {1,2,3};
int test2[3] = {4,5,6};
myCar[0] = initCar("bbb188", "BMW", test, 3);
myCar[1] = initCar("AAA-999", "VOLVO", test2, 3);
myCar[2] = initCar("CCC-999", "CITROEN", test, 3);
carCount=3;
do
{
printf("1. Show cars \n2. Add car \n");
scanf("%d", &input);
switch(input)
{
case 1:
printf("ID BRAND PICS \n");
PrintList(myCar, carCount);
break;
case 2:
AddCar(myCar, &carCount, NewCar());
printf("ID BRAND PICS \n");
PrintList(myCar, carCount);
} //break;
} while (input < 1 || input > 2); // compare as integers, not characters. Don't use < operator
return 0;
}
The code is not tested. Remaining errors are left for exercise. ;)
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 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;
}
}
}