C array with structs - c

I am a very beginner at structs and barely understand what they are useful for. I have an assignment to create an array with space for 5 points. Every point will be entered by the user.
I don't understand how to use structs with arrays. I tried this but it doesn't work at all...
#include <stdio.h>
int main(void)
{
struct Input
{
int x;
int y;
};
struct Input arr[5];
for(int i=1; i <= 5; i++)
{
printf("Enter coordinates for point #%d (x,y): ", i);
scanf("%d,%d", &arr[i].x, &arr[i].y);
}
printf("\n\nYou entered:\n");
for(int i=1; i <= 5; i++)
{
printf("Point #%d: %d, %d\n", i, arr[i].x, arr[i].y);
}
getchar();
getchar();
return 0;
}
EDIT
I am trying to calculate the average of the x coordinations, but obs.avgX doesn't work like planned, the calculation always gets 0.
#include <stdio.h>
int main(void)
{
struct Observations
{
int x;
int y;
double avgX;
double avgY;
};
struct Observations arr[5];
struct Observations obs;
for(int i=0; i < 5; i++)
{
printf("Enter coordinates for point #%d (x,y): ", i +1);
scanf("%d, %d", &arr[i].x, &arr[i].y);
}
printf("\n\nYou entered:\n");
for(int i=0; i < 5; i++)
{
printf("Point #%d: %d, %d\n", i, arr[i].x, arr[i].y);
}
obs.avgX = arr[0].y + arr[1].y + arr[2].y + arr[3].y + arr[4].y / 5;
printf("Average of X: %d", obs.avgX);
getchar();
getchar();
return 0;
}

If you need to create an array of 5 points, first you have to define what a point is.
For example:
struct Point {
int x;
int y;
};
Then you have to define an array of 5 points:
struct Point array_of_points[5];
And you can use it like this:
array_of_points[0].x = 20;
array_of_points[0].y = 10;
// etc...
array_of_points[4].x = 3;
array_of_points[4].y = 8;

SirDarius gave a nice explanation about code.
You said
barely understand what they are useful for
In fact , you can consider , that structs are a kind of "data saver" where you can store DIFFERENT or MULTIPLE types of data .
For example , using arrays , you can not store both x and y coordinates at a cell (Multiple types of Data).
Moreover , if you want to store a Student's School Info , you may want to store , his unique ID (integer) ,his name (string) , his grade (integer) and the average of each lesson (float) (Different Data). Using structs you can easily store them that way :
struct Student {
int ID;
char * name;
int grade;
float average;
}
Hope that helped to understand ,the reason why structs are really useful :)

Braces are missing as below when computing the average,
obs.avgX = (arr[0].y + arr[1].y + arr[2].y + arr[3].y + arr[4].y) / 5;
Also to print a double type variable you should be using %f as the format specifier rather than %d.

Related

Error: expected expression in C — Can't define a variable as a length of an array

I'm taking CS courses, and wrote a simple program to find an average of the given (input) amount of inputs.
#include <stdio.h>
#include <cs50.h>
int main(void)
{
int n = get_int("Please enter the number of scores: ");
int scores = [n];
for(int i=0; i<n; i++)
{
int scores[i] = get_int("Please, enter the score: ");
}
printf("Average: %f\n", average(n, scores));
}
float average(int length, int array[])
{
int sum = 0;
for(int i = 0; i < length; i++)
{
sum += sum + array[i];
}
return sum / (float)length;
}
When compiling, "expected expression" error occurs on line 10 (i.e. {int scores = [n];} —
any help or suggestions would be appreciated!!
This is invalid syntax:
int scores = [n];
If you want to define scores as an array of size n you want:
int scores[n];
Also, this doesn't do what you might expect:
int scores[i] = get_int("Please, enter the score: ");
This creates an array called scores of size i, masking the array defined previously, and attempts to initialize it with a single value instead of a list of values. If you want to assign to the existing array you want:
scores[i] = get_int("Please, enter the score: ");

calculating the sum of input numbers in c language

I want to calculate the sum of input numbers using pointer concept in c language.But when i compile the given below program correct value for sum does not appear. help me to find the mistake i have done in the below program.
#include<stdio.h>
void main()
{
int g , *p;
int sum = 0;
int x=1;
for(int i=1; i<3; i++ )
{
scanf("%d ", &g);
}
p = &g;
while( x < 3){
sum = sum + *p;
p++;
x++;
}
printf("\n sum = %d ",sum);
}
Your g is only one integer so:
Each time you call scanf("%d ", &g);, you will overwrite the previous value.
When you increment the pointer in p++;, that pointer will no longer be valid. (Where do you think it will point to?)
If you want to store three different values in g, you need to make it an array of integers.
To do this, make the following changes to your code:
int g[3] , *p; // "g" can now store three different values
int x=0; // Later on - counting from 0 thru 2 in the "while" loop
//...
for (int i=0; i<3; i++) // NOTE: Arrays begin at "0" in C!
{
scanf("%d ", &g[i]); // Store to the element indexed by "i"
}
//...
p = g; // For arrays, don't need the & operator: this will give address of first element
You can store only one number in g.
Therefore, p++; here will make p point at an invalid place.
You should allocate an array to store all input values.
Also note that you should use standard int main(void) in hosted environment instead of void main(), which is illegal in C89 and implementation-defined in C99 or later, unless you have some special reason to use non-standard signature.
#include<stdio.h>
int main(void)
{
int g[3] , *p;
int sum = 0;
int x=1;
for(int i=1; i<3; i++ )
{
scanf("%d ", &g[i]);
}
p = &g[1];
while( x < 3){
sum = sum + *p;
p++;
x++;
}
printf("\n sum = %d ",sum);
}

Passing struct array to function and calculating average in C?

Beginner here, I've been trying this for hours and can't get it to work, searched online too and couldn't find an answer.
I'm trying to write a program where you input people by putting their age and height then calculate the average of each, and the average ratio of age to height. Whenever I pass the struct to my getAverage function, it returns the address (I think) instead of the averages.
#include <stdio.h>
#include <stdlib.h>
typedef struct person
{
int age;
double height;
} Person;
double getAv (Person people[50], int max)
{
int i;
double total, retval;
total = 0;
for (i=0; i<=max; i++)
{
total = total + people[i].age;
}
retval = total / max;
return retval;
}
int main (void)
{
Person people[50];
int i;
while (i++, people[i].age>=0)
{
printf ("Person #%d\n", i);
printf ("enter an age: ");
scanf ("%d", &people[i].age);
if (people[i].age<0)
break;
printf ("enter a height: ");
scanf ("%lf", &people[i].height);
printf ("\n");
}
double averageAge;
averageAge = getAv (&people[50], i);
printf ("%.1lf\n", averageAge);
}
Haven't implemented average height or ratio yet, just trying to get average of ages to work for now. When I try taking the & out of averageAge = getAv(&people[50], I); I get a compile error that tells me it needs the &. Any help would be appreciated.
There are serveral issues in you code, the first one:
Person people[50];
int i;
while (i++, people[i].age>=0)
You are using i uninitialized, thus, incrementing a variable containing garbage (or 0 as intended, but it is impossible to guarantee)
To avoid such problems in the future enable warnings on your compiler, the compiler would have told you something like:
‘i’ is used uninitialized in this function [-Wuninitialized]
So switch to
Person people[50] = {0};
int i = 0;
It seems (based on the pre-increment operator ++i) that you want to use arrays with base 1, there is nothing wrong with that, but in your average function you are starting from 0, so use a for:
for (i = 0; ; i++)
{
...
if (people[i].age <= 0) break;
...
}
Another issue:
double averageAge;
averageAge = getAv (&people[50], i);
In this way you are passing only element 50 which is not part of your array (remember arrays are base 0 in C), to pass the entire array:
averageAge = getAv (people, i);
or
averageAge = getAv (&people[0], i);
The last one:
for (i=0; i<=max; i++)
You are including the element discarded when you was checking for age > 0, switch to:
for (i=0; i<max; i++)
A minor issue:
Iif the user enters 0 for the first element of people you end up dividing by 0
double averageAge;
averageAge = getAv (&people[50], i);
printf ("%.1lf\n", averageAge);
should be
if (i > 0)
{
double averageAge;
averageAge = getAv (people, i);
printf ("%.1f\n", averageAge); // No need to use lf (long double)
}
If you do it this way, you need to receive in your function (Person& people[], int n)
Where n is the length of the array.
We use the '&' to not do copies of the array and also you are passing only the element with index 50 in the function, simply do only (people, n)
there are mistakes in this code ,first you should initialize int i to int i=0 in mian function.
how are using this condition while (i++, people[i].age>=0) when you haven't scanned any input it's like using an uninitialized variable. you need a do-while like this
do
{
printf("Person #%d\n", i);
printf("enter an age: ");
scanf("%d", &people[i].age);
if (people[i].age < 0)
break;
printf("enter a height: ");
scanf("%lf", &people[i].height);
printf("\n");
i++;
} while (people[i-1].age >= 0);
also you are sending wrong arguments to your getAv function you should use averageAge = getAv (people, i);.
and in your function you have to remove = in this loop for (i=0; i<=max; i++) .this should be for (i=0; i<max; i++) ,otherwise the negative entered age will also be add to total and will affect the average.

Assignment to expression with array type error

in this program I try to sort customer savings descendingly. And I've tried to compile the code. And I'm still not to understand about pointer. There is an error with message "Assignment to expression with array type error". The target output of this program is tend to be the sorted customers(with their names, and account numbers). I've search in the internet about that error. But I still don't get the solution. Can someone help me to solve the error? Thanks.
#include <stdio.h>
#include <stdlib.h>
struct Data
{
long long int Savings[100], AccNo[100];
char Name[100];
};
int main ()
{
struct Data *ptr;
int n, i, j, swap = 1, x, y;
long long int max, min, temp;
printf ("Enter number of customer(s) : ");
scanf ("%d", &n);
ptr = (struct Data *) malloc (n * sizeof (struct Data));
for (i = 0; i < n; i++)
{
printf ("Enter customer %d", i + 1);
printf ("\nName : ");
getchar ();
scanf ("%[^\n]s", &(ptr + i)->Name);
printf ("Savings : ");
scanf ("%d", &(ptr + i)->Savings);
printf ("Account Number : ");
scanf ("%d", &(ptr + i)->AccNo);
printf ("\n");
}
//Sorting bubblesort
for (x = 0; x < n; x++)
{
for (y = 0; y < (n - x - 1); y++)
{
if ((ptr + y)->Savings > (ptr + y + 1)->Savings)
{
temp = (ptr + y)->Savings;
(ptr + y)->Savings = (ptr + y + 1)->Savings;
(ptr + y + 1)->Savings = temp;
}
}
}
//Print sorted
printf ("\n Sorted customers are (:\n");
for (i = 0; i < n; ++i)
{
printf ("%s\n", (ptr + i)->Name);
printf ("%d\n", (ptr + i)->Savings);
}
free (ptr);
return 0;
}
You need to compile your code with warnings enabled, the will guide
you through debugging step by step. Try to eliminate one, and
compile again. In GCC for example, you would use -Wall flag.
The numerical fields of your struct should be just numbers, not
arrays. Moreover, having their type as long long int seems a bit
too much, but I leave that on you.
Having (ptr + y)->Savings to access the y-th element of an array
of structs and the its field names Savings is technically correct,
but it's much more cleaner (thus increases readability and
maintainability) to write ptr[y].Savings. That is a general rule,
applying to the rest of your code.
I believe the above led you to make two syntactical errors when you
were reading the numerical data of the customers with scanf(),
since you know that an integer in general needs the & operator. If
you had used the clean approach from the start, you wouldn't made
those, I believe.
For long long int use the %lld format specifier, not just %d.
In Bubblesort, when you find elements that need to be swapped, then
swap the whole elements, not just their Savingss. I recommend
creating a function to do that.
scanf("%[^\n]s" doesn't make much sense, I would change it to
scanf("%99s", where 99 is the maximum size of your string, minus
one. Read more in the 2nd paragraph in scanf(“%[^\n]s”,a) question.
Putting everything together, we get:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Data {
long long int Savings, AccNo; // these should be numbers, not arrays
char Name[100];
};
void swap(struct Data* a, struct Data* b) {
struct Data tmp;
tmp.Savings = a->Savings;
tmp.AccNo = a->AccNo;
strcpy(tmp.Name, a->Name);
a->Savings = b->Savings;
a->AccNo = b->AccNo;
strcpy(a->Name, b->Name);
b->Savings = tmp.Savings;
b->AccNo = tmp.AccNo;
strcpy(b->Name, tmp.Name);
}
int main() {
struct Data *ptr;
int n, i, x, y;
printf("Enter number of customer(s) : ");
scanf("%d", &n);
ptr = malloc (n * sizeof(struct Data)); // do not cast malloc
for(i=0; i<n; i++) {
printf("Enter customer %d", i+1);
printf("\nName : ");
getchar();
scanf("%99s", ptr[i].Name); // ptr is a pointer, but now you want to actually use it as an array, so use '.'
printf("Savings : ");
scanf("%lld", &ptr[i].Savings); // needs &, just like you did for 'n'. USe `%lld' for long lont int as the format specifier.
printf("Account Number : ");
scanf("%lld", &ptr[i].AccNo); // needs &, just like you did for 'n'. USe `%lld' for long lont int as the format specifier.
printf("\n");
}
//Sorting bubblesort
for (x = 0; x < n; x++)
{
for (y = 0; y < n - x - 1; y++) // you don't need paranetheses in the stop condition
{
if (ptr[y].Savings > ptr[y + 1].Savings)
{
swap(&ptr[y], &ptr[y + 1]); // swap the whole element, not just its savings
}
}
}
//Print sorted
printf("\nSorted customers are:\n");
for(i=0; i<n; ++i)
{
printf("%s\n", (ptr+i)->Name);
printf("%lld\n", (ptr+i)->Savings);
}
free(ptr);
return 0;
}
Output (with relevant input):
Sorted customers are:
George
1
Babis
3
Theodor
20
PS: Do I cast the result of malloc? No!

Extra values when printing an array(converting from %s to %c)

I am trying to create a simple program where the user will have to enter a series of numbers and the program should output the square and the cube of the given number. However, when I try to use an array, it prints some random numbers I didn't even input. Any help would be appreciated to eliminate the unecessary input. Thank you.
#include <stdio.h>
int main()
{
char *value;
value = malloc(sizeof(20));
float answer;
int x;
int y;
scanf("%s" , value);
for(x=0; x < 20; x++)
{
y = value[x] - '0';
printf("\nThe square of %d is: %d" , y , y*y);
printf("\nThe cube of %d is: %d \n" , y , y*y*y);
}
return 0;
}
You are taking input in char and doing arithmetic operations on it.
Use this code, it will give you correct output.
#include <stdio.h>
int main()
{
int *value;
value = (int *)malloc(20 * sizeof(int));
//float answer;
int x;
int y;
for(x=0; x < 20; x++)
{
scanf("%d" , value + i);
}
for(x=0; x < 20; x++)
{
y = value[x];
printf("\nThe square of %d is: %d" , y , y*y);
printf("\nThe cube of %d is: %d \n" , y , y*y*y);
}
return 0;
}
The problem is with your malloc statement.
sizeof is used to determine the parameter size - in your case a hard-coded integer. The generated array is of size 4, which is exactly sizeof(20) instead of 20 integers which is 20*sizeof(int). It will be best to allocate the array statically if you know what size you need, see code below:
#include <stdio.h>
int main()
{
// This line sets value to an array of 20 ints
int value[20];
// Another, less favorable option, but still works:
// char *value = malloc(20 * sizeof(int))
float answer;
int x;
int y;
scanf("%s" , value);
for(x=0; x < 20; x++)
{
y = value[x] - '0';
printf("\nThe square of %d is: %d" , y , y*y);
printf("\nThe cube of %d is: %d \n" , y , y*y*y);
}
return 0;
}
The expression sizeof(20) returns the size of an int (the literal 20 is an int), which is typically only 4 bytes. In other words, you are only allocating a single integer for your array. All access outside of that single integer will result in undefined behavior.
You need to allocate sizeof(int) times the number of elements, if you want to dynamically allocate the memory. Or (which I recommend) use a normal array:
int value[20];
There is also another problem, in that you only read a single value from the user. You should probably be reading in the loop too.
But if you read in the loop, then there is really no need to even have an array to begin with, only a single int Variable which you read into, and then print its value as squared and cubed.
So the code could be simplified as
#include <stdio.h>
int main(void)
{
int value;
for (unsigned i = 0; i < 20 && scanf("%d", &value) == 1; ++i)
{
printf("The square of %d is: %d\n", value, value * value);
printf("The cube of %d is: %d\n", value, value * value * value);
}
return 0;
}
You also need to be careful of overflows when multiplying.

Resources