What is causing the error “expected ‘;’, ‘,’ or ‘)’ before ‘.’ token”? - c

I'm currently working to make an indexer for the students score, but, since I am new in C, I dont get the grasp of reading errors. Here's the error I have:
c:11:27: error: expected ‘;’, ‘,’ or ‘)’ before ‘.’ token
11 | double average(float input.score, int input.many){
c:34:13: warning: comparison between pointer and integer
34 | for(i=0; i < nas->many; i++){
c:48:3: warning: implicit declaration of function ‘average’ [-Wimplicit-function-declaration]
48 | average(sum, nas->many);
The while loop won't work properly
This is the code I work on:
#include <stdio.h>
#include <string.h>
#define MAX 100
typedef struct{
float score, avg, sum, *many;
char name[100][100];
} input;
double average(float input.score, int input.many){
float sum=0, average, a;
int i;
for(i=0; i<input.many;i++){
sum += input[i].score;
}
a = sum/input.many;
average=a;
return average;
}
int main(){
input nas[MAX];
float sum;
int choose, i, aa;
printf("How many students do you want to input?\n");
scanf(" %d",&nas->many);
for(i=0; i < nas->many; i++){
input nas[i];
printf("\nName of Student-%d\t\t: ",i+1);
scanf(" %[^\n]s", nas[i].name);
printf("The score of Student-%d\t\t: ",i+1);
scanf(" %f", &nas[i].score);
while(nas[i].score > 100 && nas[i].score < 0){
printf("Invalid! Please re-input the score\t\t: ");
scanf(" %f",&nas[i].score);
}
average(sum, nas->many);
}
printf("1--> Average of the scores");
scanf("%d", &choose);
if(choose == 1){
printf("The average of %d students is %f", nas->many, average());
}
...
else{ return 0;}
Can anybody help me to understand it? Thank you very much

Because you mustn’t use . inside a C identifier. It’s not valid. You could for instance replace it with _.
The only valid characters in a C identifier are letters, digits and underscore (ignoring Unicode).

So, you have some variables on struct thats do not make any sens, and you have some errors by send the parameters to the function and calling the function! You want the average of N students so you only can call the function after the insertion of score!
Other thing is why you need to save on every student, the sum of scores of all students, as the average of all students! And you are declaring the function always on for so when you insert for 1 student when loops back you lost your data because you declares it again!
#include <stdio.h>
#include <string.h>
#define MAX 100
typedef struct{
float score;
char name[100];
} input;
float average(input nas[], int many){
float sum=0, a;
int i;
for(i=0; i< many;i++){
sum += nas[i].score;
}
a = sum / many;
return a;
}
int main(){
input nas[MAX];
float sum;
int choose, i, many;
printf("How many students do you want to input: ");
scanf(" %d", &many);
for(i=0; i < many; i++){
printf("\nName of Student (%d): ",i+1);
scanf("%[^\n]s", nas[i].name);
printf("The score of Student (%d): ",i+1);
scanf("%f", &nas[i].score);
while(nas[i].score > 100 && nas[i].score < 0){
printf("Invalid! Please re-input the score: ");
scanf("%f", &nas[i].score);
}
}
sum = average(nas, many);
printf("\n1--> Average of the scores: ");
scanf("%d", &choose);
if(choose == 1){
for(int j=0; j < many; j++){
printf("\nName of Student: %s | Score: %f", nas[j].name, nas[j].score);
}
printf("\n\nThe average of %d students is %f\n", many, sum);
}
else{
return 0;
}
}

regarding:
scanf("%[^\n]s", nas[i].name);
are you expecting the user entered field name to be followed by a '\n' then a s?
Probably not.
Also, this statement does not remove the '\n' from stdin.
Therefore, IF anything, that s should be replaced with a space (so any trailing 'white space' is consumed. However, that is 'always' a bad idea.)
Strongly suggest using:
scanf("%[^\n]", nas[i].name); // note: no trailing `s`
note the next call to scanf() with a %f specifier will consume any leading 'white space'.
regarding:
scanf(" %d",&nas->many);
This may result in the first element in the array nas[] field many being set, but a much better method is:
scanf(" %d",&nas[0]->many);
regarding: right after the for() statement:
input nas[i];
This is declaring/re-declaring a new array with however many elements the i variable indicates. Probably not what you want to do.
regarding:
char name[100][100];
This is declaring a 2 dimensional array of 100 entries, with each entry being 100 characters. However, when ever the posted code references this 2d array, all that is given is name. The result will be all names will overlay each other in the first [0] entry
regarding:
scanf("%[^\n]s", nas[i].name);
besides the previously mentioned problem with the format string, and with using name without any indexing, the specifier: %[\n] does not limit the length of a name. Suggest:
scanf("%99[^\n]", nas[i].name[i]);
There are LOTS of other problems in the posted code besides those mentioned above.

Related

Having problems with 2D char arrays

So I've got an assignment where my program asks the brand (10 letters), model (10 letters), age (1986 - 2019) and cost (positive real number) of 10 cars and then wants the program to check which car is the oldest and to print out it's brand and model. I don't have a problem with the first part but with the second part.
The code is:
//First part
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define C 10
#define M 11
int main(void)
{
char brand[C][M];
char model[C][M];
int year[C];
float cost[C];
int i, len1, len2, min;
for(i=0; i<C; i++){
printf("Car %d\n", i+1);
do{
printf("Brand: ");
scanf("%s", brand[i]);
len1 = strlen(brand[i]);
} while(len1<0 || len1>10);
do{
printf("Model: ");
scanf("%s", model[i]);
len2 = strlen(model[i]);
} while(len2<0 || len2>10);
do{
printf("Year: ");
scanf("%d", &year[i]);
} while(year[i]<1986 || year[i]>2019);
do{
printf("Cost: ");
scanf("%d", &cost[i]);
} while(cost[i]<=0);
}
//Second part
year[0] = min;
for(i=0; i<10; i++)
if(year[i] < min){
min = year[i];
printf("\nThe oldest car is %s %s\n", brand[i], model[i]);
}
For some reason it either prints out gibberish in the place of brand[i] or if I lose the columns of the if statement prints out all the car brands and their models, where I only want the oldest one.
Aside from scanf not being recommended there are some problems with this code, first when you read the brand and model you do:
do{
printf("Brand: ");
scanf("%s", brand[i]);
len1 = strlen(brand[i]);
} while(len1<0 || len1>10);
The problem here is that you first write the string to brand[i] and then check if it's too long, but you have already written it into the array so if the string is longer than your space you already have a buffer overflow. Limit the size you can read with scanf using scanf("%10s, brand[i]) or better yet use fgets(brand[i], sizeof(brand[i]), stdin).
Next in the second part you use min without initializing it, and you overwrite the content of year[0] with it. You probably wanted something like:
min = 2020; // or a number that will be bigger than all your cars anyway
int older = 0;
i = 0;
for(i=0; i<C; i++){ // Use C here, you have it might as well use it instead of magic numbers
if(year[i] < min){
older = i;
min = year[i];
}
}
printf("\nThe oldest car is %s %s\n", brand[older], model[older]);
but bare in mind that this solution will print multiple cars if they are the oldest ones and have the same year

Average generates a negative decimal number

I created a function called average that will calculate the average age. How ever it is generating a strange negative decimal point.It was working fine until I put the strcmp function to people who have enter Texas. Example ages: 20 50 20 30 & 40 generate The average age is -243454739.00.
Can someone point me in the right direction, Thanks.
#include <stdio.h>
#include <string.h>
int main()
{
//function decleration
float average ( int A, int n);
//int deleceration
char names, states, statedata[100], namedata[100];
int agedata[100], age, count = 0, A, n, avg;
float a;
//Get User Input
printf("Enter Number of family members being enter into program \n");
scanf("%d", &n);
//Name Loop
for (names=0; names<n; ++names)
{
printf("Enter Family members name:\n");
scanf("%s", &namedata);
//Age Loop
for (age=0; age<1; ++age)
{
printf("Enter family members age:\n");
scanf("%d", &agedata[age]);
A +=agedata[age];
count= count + 1;
//State Loop
for (states=0; states<1; ++states)
{
printf("Enter Family members state:\n");
scanf("%s", &statedata);
//strcmp function for state name "Texas" Selection
if (strcmp(statedata,"texas")==0)
{
printf("Family members who live in texas\n");
printf("%s\n", namedata);
}
}
}
}
// Average function call
a = average(A, n);
printf("The average age is %.2f\n", a);
return 0;
}
//A declarator
float average( int A, int n){
float average;
average = A / n;
return average;
}
Initialize A to 0 in main(). Uninitialized local variables have indeterminate values in C.
Other issues:
1)
scanf("%s", &namedata);
scanf("%s", &statedata);
Shoud be
scanf("%s", namedata);
scanf("%s", statedata);
Because scanf() expects a char* when for format specifier %s whereas you are passing char(*)[100].
2)
All the values of ages are using type int. So the having the function average() return a float is still going to give an int result.
Change the type A (in main()) and the function parameter A (in average()) to float.
3)
Your inners are running 0..1 i.e. only once. So you don't really need those loops.

array of struct C scanf with float

hello im trying to work with a struct of students but everytime i ask the input of grade the program stop running and i dont know why. im using Turbo C++ 4.0. if i use grades as int the program doesnt stop but when i use them as float the program stop running. please any help heres the code:
#include<conio.h>
#include<stdio.h>
#define num 2
struct student {
char name[50];
float cal1;
float cal2;
float prom;
} est[num];
int main () {
int i=0;
clrscr();
for(i=0;i<=num;i++) {
printf("\nName of student[%d]:",i);
scanf("%s",&est[i].name);
printf("\nGrade #1 [%d]:",i);
scanf("%f",&est[i].cal1);
printf("\nGrade #2 [%d]:",i);
scanf("%f",&est[i].cal2);
}
for(i=0;i<=num;i++) {
printf("\nStudent [%d]:",i);
printf("\nName: ");
printf("%s",est[i].name);
printf("\nGrade #1: ");
printf("%f",est[i].cal1);
printf("\nGrade #2: ");
printf("%f",est[i].cal2);
}
getch();
return 0;
}
You define:
#define num 2
struct student { … } est[num];
and you loop on:
for (i = 0; i <= num; i++)
{
…scanning code…
}
This is a buffer overflow. It attempts to read 3 students worth of data, with the third student's data going into the space after the space allocated for est. This is a buffer overflow and leads to undefined behaviour; anything can happen and it is OK.
In C, get used to using the idiomatic for loop:
for (i = 0; i < limit; i++)
In the code that reads data, you need to check that the scanf() calls succeed:
printf("\nName of student[%d]:",i);
if (scanf("%s", est[i].name) != 1) // Note no & for strings
…handle error…
printf("\nGrade #1 [%d]:",i);
if (scanf("%f", &est[i].cal1) != 1)
…handle error…
printf("\nGrade #2 [%d]:",i);
if (scanf("%f", &est[i].cal2) != 1)
…handle error…
The printing loop should not attempt to print more entries than were actually read, which might be less than num if there was an error. Obviously, it needs to be in the idiomatic form too, but you should really be using:
int j;
for (j = 0; j < i; j++)
or something similar so if only 1 entry was read, you only print that one entry.
here is an example of the code that
cleanly compiles, links, runs
I did not use conio.h as it is non-standard
(and not available on my machine)
this code still needs the error checking for returned value from scanf added
#include <stdio.h>
//#include <conio.h>
#include <stdlib.h> // system()
#define num (2)
struct student
{
char name[50];
float cal1;
float cal2;
float prom; // only one ';'
};
// separated definition, above, from declaration, below
struct student est[num];
int main ()
{
int i=0;
system( "cls" );
//clrscr();
for(i=0;i<num;i++) // note correction to for statement
{
printf("\nName of student[%d]:",i);
scanf(" %49s", est[i].name); // note correction to format string
// and using array
// as degraded into pointer
// otherwise
// unknown where trying to place data
// added vertical spacing for readability
printf("\nGrade #1 [%d]:",i);
scanf("%f", &est[i].cal1);
// added vertical spacing for readability
printf("\nGrade #2 [%d]:",i);
scanf("%f", &est[i].cal2);
}
for(i=0;i<num;i++) // note correction to 'for' statement
{
printf("\nStudent [%d]:",i);
printf("\nName: ");
printf("%s",est[i].name);
printf("\nGrade #1: ");
printf("%f",est[i].cal1);
printf("\nGrade #2: ");
printf("%f",est[i].cal2);
}
getchar(); // this will input the final newline, so will exit immediately
//getch();
return 0;
} // end function: main

while loop asks user input one time only

#include <stdio.h>
#include <stdlib.h>
struct the_struct
{
char FirstName[20];
char LastName[32];
int Score[20];
};
int main ()
{
int i,n;
struct the_struct *ptr[100];
printf("how many students?\n");
scanf("%d",&n);
while (i<=n);
{
i==0;
ptr[i] = malloc(sizeof(struct the_struct));
printf("Enter First Name \n");
scanf("%s",ptr[i]->FirstName);
printf("Enter Last Name \n");
scanf("%s",ptr[i]->LastName);
printf("Enter Score? \n");
scanf("%s",ptr[i]->Score);
printf("%s %s %s\n",ptr[i]->FirstName,ptr[i]->LastName,ptr[i]->Score);
i++;
}
}
hey guys, so when i enter the first input, it goes only once without going on for the number the user inputs, i tried the for loop but same result.
still learning C so my apology if i misunderstood something.
Thanks in advance.
Your while loop is problematic. You could rewrite it as:
for (i = 0; i < n; ++i)
{
ptr[i] = malloc(sizeof(struct the_struct));
printf("Enter First Name \n");
scanf("%s",ptr[i]->FirstName);
printf("Enter Last Name \n");
scanf("%s",ptr[i]->LastName);
printf("Enter Score? \n");
scanf("%s",ptr[i]->Score);
printf("%s %s %s\n",ptr[i]->FirstName,ptr[i]->LastName,ptr[i]->Score);
}
And since you use %s to read and print Score, you should declare it as char Score[20]; instead of int.
The problem is that i is uninitialized. Therefore, the loop while (i <= n) has undefined behavior, and can end at any time.
Add int i = 0 initializer to fix this problem.
Notes:
i == 0 expression at the beginning of the loop has no effect
Since i starts at zero, your while loop should be while (i < n), not <=.
You should check the results of scanf to see if the user entered something meaningful
You should specify the size of the array into which you read a string, e.g. scanf("%31s",ptr[i]->LastName); This prevents buffer overruns.

C programming return value odd

I tried to search this everywhere, but it's kind of difficult to word, it's most likely a simple fix. Basically when I go through my program that is supposed to compute the average rainfall for a year, it comes out with a very large number, however, I thought it may have been just that I was doing the arithmetic wrong or had a syntax error of some sort, but that was not the case, when I checked the value that the function returned it was the proper value.
#include <stdio.h>
#include <string.h>
void getData(float *, float *);
int main()
{
char state[2], city[81];
float rainFall[12], outputAverage, *pAverage;
printf("Name Here\n");
printf("Please enter the state using a two letter abreviation: ");
gets(state);
printf("Please enter the city : ");
gets(city);
pAverage = &outputAverage;
(getData(rainFall, pAverage));
printf("%.2f", outputAverage);
return (0);
}
void getData(float *rainFall, float *pAverage)
{
int i;
float total;
for (i=0; i<12; i++)
{
printf("Please enter the total rainfall in inches for month %d: ", i+1);
scanf("%f", &rainFall[i]);
total += rainFall[i];
}
*pAverage = total / 12;
}
you need to initialize total
float total = 0.0;
Initialize the total to 0
Why you make it complicated? Why not just
return total / 12 ?
and called it like
outputAverage = getData(rainfall)
This is a classic problem in C programming. You are mixing strings and numbers on the input. You are better off reading the input into a string and then, using sscanf to parse it properly.
You have uninitialized variable total which is taking garbage value, thus you see a very large answer.
changed your main.. have a look and let me know if you have understood what changes i have made?
#include <stdio.h>
#include <string.h>
void getData(float *);
int main(int argc, char*argv[])
{
char state[3]={0}, city[81]={0};
float outputAverage;
printf("Name Here\nPlease enter the state using a two letter abreviation: ");
scanf("%s",state);
printf("Please enter the city : ");
scanf("%s",city);
getData(&outputAverage);
printf("The Average Rainfall recorded for the year is %.2f\n", outputAverage);
return 0;
}
void getData(float *pAverage)
{
int i;
float rainFall[12]={0}, total=0;
for (i=0; i<12; i++)
{
printf("Please enter the total rainfall in inches for month %d: ", i+1);
scanf("%f", &rainFall[i]);
total += rainFall[i];
}
*pAverage = total / 12;
}
However instead of using gets you should use fgets but i forgot how to counter the issue of using simultaneous fgets to read input from the standard input stream.
Also initialize the total variable as you are adding in the loop new values to existing value in that variable which would not necessarily add to zero as the premier element. so it could be any garbage value + loop values.
I understand you are practicing pointer concept so you passed the address of the array of floats to your second function but if the rainfall function is not useful in main, Better to restrict the same where it would be useful

Resources