What I'm trying to do is get student's name and score in three subjects in the form of a structure array and print their name and average score.
Where is my mistake?
#include <stdio.h>
typedef struct
{
char name[5];
int Kor; //yeah the three subjects
int Eng;
int Math;
}data;
double avg(int a, int b, int c) //to get the average
{
double m;
m = (a + b + c) / 3;
return m;
}
int main()
{
data group[3];
for (int i = 0; i < 3; i++)
{
scanf("%s %d %d %d", group[i].name, group[i].Kor, group[i].Eng, group[i].Math);
}
for (int j = 0; j < 3; j++)
{
printf("%s %lf\n", group[j].name, avg(group[j].Kor, group[j].Eng, group[j].Math));
}
return 0;
}
One thing you should make sure and do is compile with most/all compiler warning flags on. In your case, when I compiled your program with GCC, using the flags -W -Wall -Wextra, I got the following warnings:
<source>: In function 'main':
<source>:23:20: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'int' [-Wformat=]
23 | scanf("%s %d %d %d", group[i].name, group[i].Kor, group[i].Eng, group[i].Math);
| ~^ ~~~~~~~~~~~~
| | |
| int * int
and the same warning for group[i].Eng and group[i].Math.
These compiler warnings are very often actually errors of yours, which, at runtime, will result in the program crashing or producing garbage. In your case, you need to pass the address of the value you want to read from the input.
This does not mean that's the only issue with your code, but you should really let the compiler help you before asking us for help.
I change the scanf, '&' operator is used to access to the address in the memory location. scanf("%d",&a) means that the value entered from the keyboard must be stored in the memory LOCATION where which is given the name 'a'.
and change the calculating function of the average because you are using the integer division version of operator/, which takes 2 ints and returns an int. In order to use the double version, which returns a double, at least one of the ints must be casted to a double.
#include <stdio.h>
typedef struct
{
char name[5];
int Kor; //yeah the three subjects
int Eng;
int Math;
}data;
double avg(int a, int b, int c) //to get the average
{
double m;
m = (a + b + c) / 3.0;
return m;
}
int main()
{
data group[3];
for (int i = 0; i < 3; i++)
{
printf("enter your name ,Kor grade ,Eng grade ,Math grade\n");
scanf("%s %d %d %d", group[i].name, &group[i].Kor, &group[i].Eng, &group[i].Math);
}
for (int j = 0; j < 3; j++)
{
printf("name:%s avg:%lf\n", group[j].name, avg(group[j].Kor, group[j].Eng, group[j].Math));
}
return 0;
}
Related
I'm running into this problem which I think should not happen:
Here are the errors I'm getting.
Sorry for bad formatting, coding on notepad and cntr c&v to compiler (tend to do this from time to time)
~/workspace/Exam1 $ gcc -g payload.c -o payload
payload.c: In function ‘main’:
payload.c:63:31: warning: initialization from incompatible pointer type [enabled by default]
struct payload* calcVal = getCalc(arr, num);
^
payload.c:65:36: error: dereferencing pointer to incomplete type
printf("OddSum : %d\n", calcVal->sumOdd);
^
payload.c:66:40: error: dereferencing pointer to incomplete type
printf("Even Count : %d\n", calcVal->evenCount);
^
payload.c:67:37: error: dereferencing pointer to incomplete type
printf("Minimum : %d\n", calcVal->min);
^
payload.c:68:37: error: dereferencing pointer to incomplete type
printf("Maximum : %d\n", calcVal->max);
I honestly do not understand what the problem is and why I keep running into this. Am I passing struct wrong?
#include<limits.h> //for min/max
#include <stdio.h>
#include <stdlib.h>
struct payLoad{
int sumOdd;
int evenCount;
int min;
int max;
};
struct payLoad* getCalc(int *arr, int n){
int i = 0;
int min= INT_MAX;
int max = INT_MIN;
int sum = 0;
int even = 0;
struct payLoad* calcVal = malloc(sizeof(struct payLoad)); //watch spelling
for(i=0;i <n;++i){
if(arr[i]%2==0){
++even;
}
if (arr[i] < min){
min = arr[i];
}
}
if (arr[i] > max){
max = arr[i];
}
if(arr[i]%2==1){
sum = sum + arr[i];
}
calcVal->sumOdd = sum;
calcVal->evenCount = even;
calcVal->max = max;
calcVal->min = min;
return calcVal;
}
int main(){
int num;
int i=0;
//int min= INT_MAX:
//int max = INT_MIN:
int sum = 0;
printf("Enter the number of array element: ");
scanf("%d", &num);
int *arr = (int *)malloc(num*sizeof(int));
for(i=0;i <num;++i){
printf("Enter the value: ");
scanf("%d", &arr[i]);
}
struct payload* calcVal = getCalc(arr, num);
printf("OddSum : %d\n", calcVal->sumOdd);
printf("Even Count : %d\n", calcVal->evenCount);
printf("Minimum : %d\n", calcVal->min);
printf("Maximum : %d\n", calcVal->max);
}
Edit: fixed typos and spellings, removed link, cntr c&v errors
Your program is having several typo's, like at several places you have:
struct payload
^
payload should be payLoad.
Here:
if(arr[i]%2==1)
sum = sum + arr[i];
}
You forgot to put {. It should be:
if(arr[i]%2==1) {
sum = sum + arr[i];
}
In main():
int num,
Instead of , it should be ;.
Again in main():
printf("OddSum : %d\n", calcVal->oddSum);
Look at your struct payLoad declaration and you will find that it is having a member sumOdd and not oddSum.
The compiler must be reporting all these as errors. Take a close look at them, try to identify the cause, fix it and build it again.
Whatever memory you are allocating dynamically you should free it. Once the program terminates the memory owned by it will be freed automatically but as a good programming practice, you should explicitly free the memory allocated dynamically once you are done with it.
The program is about function making an average. I get an error:
error: expected ';', ',' or ') before numeric constant
within the avg_array() function whenever I build it. Help would be appreciated, thanks!
#include <stdio.h>
#define SIZE 5
// Prototypes
int avg_array (int*, int);
main()
{
int values[SIZE];
int avg;
int i;
printf("Enter 5 numbers please. \n");
for(i=0; i<SIZE; i++)
{
scanf("%d", &values[i]);
}
avg = avg_array(values, SIZE);
printf("\n The avg of the array is %d \n", avg);
getchar();
getchar();
} // end main()
/* Implement avg_array() WHERE THE ERROR PERTAINS */
avg_array(int my_array[], int SIZE)
{
int sum;
int i;
int fxn_average;
for(i=0; i<SIZE; i++)
{
sum = sum + my_array[i];
}
fxn_average = (sum/SIZE);
return (fxn_average);
}
You are using the identifier SIZE as an argument. This is also a macro that gets converted to 5 by the preprocessor. After the preprocessor applies the macros, it would look like
avg_array (int my_array[], int 5)
Since 5 is a numeric constant instead of an identifier, it generates an error. Change the variable name.
It looks like you also have a function signature missing a return type, which should match the prototype declared above. Try this instead:
int avg_array (int *my_array, int size)
{
int sum = 0;
int i;
for(i=0; i<size; i++)
{
sum = sum + my_array[i];
}
return sum/size;
}
The variable sum should be initialized to 0. The local variable fxn_average is not needed because you can use just return sum/size; at the end instead.
I changed the type of the first argument from int[] (array of int) to int * (pointer to int) so the function definition matches the prototype given in the question. The function was declared as
int avg_array (int*, int);
These arguments have no identifiers; only their types are specified. This is valid C, but many style guides prescribe against it since naming arguments helps the reader understand meaning or intent. If you are writing a programming interface, for example, all the programmer will likely see is the function prototypes in a header file. It must be clear what the arguments are to write a correct function call. Anyway, adding in identifiers looks like:
int avg_array (int *my_array, int size);
which is the same as in the definition I used above.
So I'm brand new to C and playing around with memory allocation for arrays. I'm trying to create a program that will dynamically allocate space using malloc to reverse an array of floating point numbers.
#include <stdio.h>
#include <stdlib.h>
struct Rec {
float * x;
int size;
};
int main(){
struct Rec a[50];
int i, y;
printf("Enter the number of floating point numbers: ");
scanf("%d", &y);
x = malloc(y * sizeof(struct));
printf("Enter 5 floating point numbers: \n");
for(i = 0; i < sizeof(struct); i++){
scanf("%.3f", &x[i]);
}
printf("The numbers in reverse order are: \n");
for(i = --sizeof(struct); i >= 0; i--){
printf("%f \n", a[i]);
}
}
During compilation, the following errors are generated:
error: use of undeclared identifier 'x'
*x = malloc(y * sizeof(struct);
^
test.c:14:25: error: declaration of anonymous struct must be
a definition
*x = malloc(y * sizeof(struct);
^
test.c:14:32: error: type name requires a specifier or qualifier
*x = malloc(y * sizeof(struct);
^
test.c:14:31: error: type name requires a specifier or qualifier
x = malloc(y * sizeof(struct));
^
test.c:14:24: note: to match this '('
*x = malloc(y * sizeof(struct);
^
test.c:25:3: error: expected '}'
}
^
test.c:9:11: note: to match this '{'
int main(){
^
Your pointer x is part of the structure which is stored in an array. You probably want to access your "x" through the structure. So instead of
x = malloc(y * sizeof(struct));
You probalby want
a[some index].x = malloc(y * sizeof(struct));
This above line will compile but will most likely give you incorrect results. Since you want to allocate it, you want it to be the size of the variable that you are planning to store there, not the size of the struct.
I should mention that there are other problems. You can't iterate through a structure that way. You want to instead iterate over the length of the array (of structs) instead.
There are a lot of issues with your code. I would advise you to practice more with C basics before attempting to do this. Here is approximation of what you might have wanted to achieve with your code:
#include <stdio.h>
#include <string.h>
// This structure can hold array of floats - and their size
struct Rec
{
float * x;
int size;
};
int main()
{
// Declare variable of type rec
struct Rec a;
int i, y;
// How many floats to store? This could also be stored in a.size instead of y
printf("Enter the number of floating point numbers: ");
scanf("%d", &y);
// Create and populate dynamic array
a.x = malloc(y * sizeof(float));
printf("Enter floating point numbers: \n");
for(i = 0; i < y; i++)
{
scanf("%.3f", &a.x[i]);
}
// Print
printf("The numbers in reverse order are: \n");
for(i = y-1; i >= 0; i--)
{
printf("%f \n", a.x[i]);
}
free(a.x);
return 0;
}
I'm just trying to read the elements from a text file that has all the numbers and pass it as an argument to the "frequency()" function given below.However,It shows up an error saying that
"argument of type int is incompatible with argument of type (int*)" . I tried everything to convert (int*) to int but ended up miserably..below posted is my C code.
void main()
{
FILE*file = fopen("num.txt","r");
int integers[100];
int i=0;
int h[100];
int num;
int theArray[100];
int n,k;
int g;
int x,l;
while(fscanf(file,"%d",&num)>0)
{
integers[i]=num;
k =(int)integers[i];
printf("%d\n",k);
i++;
}
printf ("\n OK, Thanks! Now What Number Do You Want To Search For Frequency In Your Array? ");
scanf("\n%d", &x);/*Stores Number To Search For Frequency*/
frequency(k,n,x);
getch();
fclose(file);
}
void frequency (int theArray [ ], int n, int x)
{
int count = 0;
int u;
// printf("%d",n);
for (u = 0; u < n; u++)
{
if ( theArray[u]==x)
{
count = count + 1 ;
/*printf("\n%d",theArray[u]);*/
/* printf("\n%d",count);*/
}
else
{
count = count ;
}
}
printf ("\nThe frequency of %d in your array is %d ",x,count);
}
So the idea is that the elements read through "num.txt" are stored in an array 'k' and the same array has to be passed in the frequency function! However,in my case it is saying "argument of type int is incompatible with argument of type(int*).
frequency(k, n, x);
|
|
+---int ?
But
frequency (int theArray [ ], int n, int x)
|
|
+ accepts an int*
Call your function as
frequency ( integers, i, x );
You never initialized n and theArray in your main, simply declaring them will not magically pass them in other functions.
When you call the frequency function, you're passing in the int k as the first argument. I think it's worth correcting your statement that k is an array. It is not. You declare it as an int. This is where your type error is coming from because it expects an int * (because of the int[] argument).
Perhaps you mean to pass in integers instead of k?
If I leave all variables as int I get 32. The division is supposed to give me 32.5 so I thought that changing everything to double would do it, but it just gives me zero...
Here is the code (everything in int):
#include <stdio.h>
#include <stdlib.h>
void sommeTableau(int tableau[], int tailleTableau, int *x, int *average);
int main(int argc, char *argv[])
{
int tableau[4] = {30, 50, 50};
int *x = 0;
int *average = 0;
const int tailleTab = 4;
sommeTableau(tableau, tailleTab, &x, &average);
printf("The average is %d\n", average);
return 0;
}
void sommeTableau(int tableau[], int tailleTableau, int *x, int *average)
{
int i = 0;
for (i = 0 ; i < tailleTableau ; i++)
{
*x = *x + tableau[i];
}
*average = *x/tailleTableau;
}
So this works and gives me 32... Now if I change everything to double and %d to %f in the printf function, it gives me zero and I don't understand why...
There is lots of mistakes in your code. I corrected all of them
#include <stdio.h>
#include <stdlib.h>
void sommeTableau(int tableau[], int tailleTableau, int *x, double *average);
int main(int argc, char *argv[])
{
int tableau[4] = {30, 50, 50};
int x = 0;
double average = 0;
const int tailleTab = 4;
sommeTableau(tableau, tailleTab, &x, &average);
printf("The average is %lf\n", average);
return 0;
}
void sommeTableau(int tableau[], int tailleTableau, int *x, double *average)
{
int i = 0;
for (i = 0 ; i < tailleTableau ; i++)
{
*x = *x + tableau[i];
}
*average = (double)(*x)/(double)tailleTableau;
}
You are passing x and average as null pointer. Thats why your code is giving segmentation fault.
As per you describtion please check(http://codepad.org/z8fVUTe5).
#include <stdio.h>
#include <stdlib.h>
void sommeTableau(int tableau[], int tailleTableau, int *x, int *average);
int main(int argc, char *argv[])
{
int tableau[4] = {30, 50, 50};
int x = 0;
int average = 0;
const int tailleTab = 4;
sommeTableau(tableau, tailleTab, &x, &average);
printf("The average is %d\n", average);
return 0;
}
void sommeTableau(int tableau[], int tailleTableau, int *x, int *average)
{
int i = 0;
for (i = 0 ; i < tailleTableau ; i++)
{
*x = *x + tableau[i];
}
*average = *x/tailleTableau;
}
Output:-
The average is 32
One of your problems lies here:
int *x = 0;
int *average = 0;
sommeTableau(tableau, tailleTab, &x, &average);
Those first two lines should be:
int x = 0;
int average = 0;
This is evident from the warnings you should be getting, assuming you're using a decent compiler:
qq.c: In function ‘main’:
qq.c:13: warning: passing argument 3 of ‘sommeTableau’ from incompatible pointer type
qq.c:4: note: expected ‘int *’ but argument is of type ‘int **’
qq.c:13: warning: passing argument 4 of ‘sommeTableau’ from incompatible pointer type
qq.c:4: note: expected ‘int *’ but argument is of type ‘int **’
In addition, you don't need _everything to be a double, just the average, so you should only change the type of that variable and match that with the parameters passed to the function.
It will also be necessary to cast the total *x to a double before doing the division, so that it knows you don't mean integer division.
With those changes, the output changes from:
The average is 4.000000
(for me) to the correct:
The average is 32.500000
See the following program for more detail:
#include <stdio.h>
#include <stdlib.h>
void sommeTableau(int tableau[], int tailleTableau, int *x, double *average) {
int i;
for (i = 0 ; i < tailleTableau ; i++)
*x = *x + tableau[i];
*average = ((double)(*x))/tailleTableau;
}
int main (void) {
int tableau[4] = {30, 50, 50};
int x = 0;
double average = 0;
const int tailleTab = 4;
sommeTableau(tableau, tailleTab, &x, &average);
printf("The average is %lf\n", average);
return 0;
}
int *x = 0;
int *average = 0;
This is defining two pointers and setting the pointers to zero -- which, in a pointer context translates to a null pointer. So, you have to pointers to nothing.
sommeTableau(tableau, tailleTab, &x, &average);
Here, you're passing the addresses of those pointers to the function, so the function is really receiving an int **.
printf("The average is %d\n", average);
This is then taking the value of the pointer -- the address its holding -- and (probably) treating that bit pattern as an int. This is technically undefined behavior, but on many machines, a pointer it enough like an int for it to appear to work. The same will almost never be true with a floating point number though.
What you want to do here is define two ints (or two doubles) and pass their addresses to your function:
double x=0.0, average=0.0;
sommeTableau(tableau, tailleTab, &x, &average);
// ...
printf("%f, %f\n", x, average);
It doesn't actually work.
Here you define x and average as NULL pointers to int:
int *x = 0;
int *average = 0;
And here instead of pointers to int you pass pointers to pointers to int:
sommeTableau(tableau, tailleTab, &x, &average);
Which is clearly wrong. You should enable compiler warnings to see such problematic places and correct them.
Here the correction would be:
int x = 0;
int average = 0;
Now, here:
printf("The average is %d\n", average);
You are lying to printf() about what you're going to give it (an int, because of %d), but you're actually giving it a pointer to int. The above correction fixes this. If you lie to printf() about the type of some parameter, anything can happen. If your compiler is gcc and you enable warnings, you can spot this kind of problems as well.
Something is terribly wrong here -- you're defining x and average as pointer variables in main, which if you are lucky is the same size as an int, but may result in undefined behavior.
Remove the * from the local variable declarations of x and average in main and it may actually work.
Also, in sommeTableau, both operands of the division (*x and tailleTableau) are int, so integer division is performed and the remainder discarded prior to assignment to *average.