I am getting errors during the compilation of this C program and is related to the declaration of the function. What is the problem here? When I declare void display(student); it shows a warning but if I change to void display(struct student st) it shows some errors.
#include<stdio.h>
void display(student);
void read_student(student);
struct student{
int roll;
char name[20],depart[20],sex,result;
float percent,marks[5],total;
};
void main(){
int n;
printf("enter the no of data you want to enter ??");
scanf("%d",&n);
struct student s[n];
for(int i=0;i<n;i++)
read_student(&s[i]);
printf("\n---------------------------------------------------Result Sheet --------------------------------------------------------------------");
printf("\nRoll No.\tName\t\tSex\tDepartment\t\tMarks\t\t\t\tTotal\tPercentage\tResult ");
printf("\n----------------------------------------------------------------------------------------------------------------------------------------");
printf("\n \t\t\t\tA\tB\tC\tD\tE\n");
printf("----------------------------------------------------------------------------------------------------------------------------------------");
for(int i=0;i<n;i++)
display(s[i]);
}
void display(struct student st){
printf("\n%2d\t%10s\t\t%c\t%10s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%4.2f\t %2.2f\t\t%c\n",st.roll,st.name,st.sex,st.depart,st.marks[0],st.marks[1],st.marks[2],st.marks[3],st.marks[4],st.total,st.percent,st.result);
}
void read_student(struct student *std){
int c=0,i;
printf("Enter the roll no:");
scanf("%d",&std->roll);
printf("enter the name:\n");
scanf("%s",std->name);
printf("enter Sex:\n");
scanf(" %c",&std->sex);
printf("Enter the department:\n");
scanf("%s",std->depart);
printf("enter the marks in 5 subjects:\n");
for(i=0;i<5;i++){
scanf("%f",&std->marks[i]);
std->total=std->total+std->marks[i];
if(std->marks[i]>=40)
c++;
}
if(c==5)
std->result='p';
else
std->result='f';
std->percent=(std->total/500)*100;
}
The compiler needs to know what struct student is, when using it elsewhere in the code, for example declaring a function with it as type of an argument/parameter. The compiler reads the source file from top to bottom. You need to declare the structure before you use it as a type in the declaration of a function:
struct student; // forward declaration of structure `student`.
void display(struct student); // ok, because `struct student` is declared before.
void read_student(struct student*); // ok, because `struct student` is declared before.
struct student{ // definition of structure `student`.
int roll;
char name[20],depart[20],sex,result;
float percent,marks[5],total;
};
Alternatively, you can define the structure before the declarations of the functions:
struct student{ // define the structure `student` before the function declarations.
int roll;
char name[20],depart[20],sex,result;
float percent,marks[5],total;
};
void display(struct student);
void read_student(struct student*);
Another way would be to put the definitions of the functions read_student and display before main(), but after the the definition of the structure student. In this way you can omit the separate declarations of the functions read_student and display and of course the forward declaration of the structure student as well:
#include<stdio.h>
struct student{
int roll;
char name[20],depart[20],sex,result;
float percent,marks[5],total;
};
void read_student(struct student *std){
int c=0,i;
printf("Enter the roll no:");
scanf("%d",&std->roll);
printf("enter the name:\n");
scanf("%s",std->name);
printf("enter Sex:\n");
scanf(" %c",&std->sex);
printf("Enter the department:\n");
scanf("%s",std->depart);
printf("enter the marks in 5 subjects:\n");
for(i=0;i<5;i++){
scanf("%f",&std->marks[i]);
std->total=std->total+std->marks[i];
if(std->marks[i]>=40)
c++;
}
if(c==5)
std->result='p';
else
std->result='f';
std->percent=(std->total/500)*100;
}
void display(struct student st){
printf("\n%2d\t%10s\t\t%c\t%10s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%4.2f\t %2.2f\t\t%c\n",st.roll,st.name,st.sex,st.depart,st.marks[0],st.marks[1],st.marks[2],st.marks[3],st.marks[4],st.total,st.percent,st.result);
}
int main(){
int n;
printf("enter the no of data you want to enter ??");
scanf("%d",&n);
struct student s[n];
for(int i=0;i<n;i++)
read_student(&s[i]);
printf("\n---------------------------------------------------Result Sheet --------------------------------------------------------------------");
printf("\nRoll No.\tName\t\tSex\tDepartment\t\tMarks\t\t\t\tTotal\tPercentage\tResult ");
printf("\n----------------------------------------------------------------------------------------------------------------------------------------");
printf("\n \t\t\t\tA\tB\tC\tD\tE\n");
printf("----------------------------------------------------------------------------------------------------------------------------------------");
for(int i=0;i<n;i++)
display(s[i]);
}
At the declaration of functions you can omit identifiers of parameters, but not the type of parameters.
It is also not permissible to use the structure student without preceding the struct keyword as you tried it with:
void display(student);
since you use the structure student by its definition:
struct student{
...
};
If you would use a typedef like for example:
typedef struct student{
...
} student;
You could omit the struct keyword, but if you use a typedef or just use the structure as it is, is a kind of controversy topic amongst the community with regards to readibility. All references to that, you can see on the answers to these questions:
typedef struct vs struct definitions
Why should we typedef a struct so often in C?
I personally recommend to keep on using the struct variant, even if it requires a little bit more typing with the keys, but makes your code a little bit clearer.
Related
I'm trying to print the entered values from struct. Program is able to get all input values but after show() method call it does jumps out of the program in exit without displaying my entered values.
I'm not getting any error or warning at all.
Code:
#include<stdio.h>
#include<string.h>
struct Book{
char *title;
short price;
};
void show(struct Book b[],const short n){
short i;
printf("\nBOOK DETAILS");
for(i=0;i<n;i++){
printf("\nRecord no %d / %d",i+1,n); //exits after displaying this line
printf("\nTitle : %s \nPrice: %d",b[i].title, b[i].price);
}
}
void get(struct Book b[],const short n){
short i;
for(i=0;i<n;i++){
printf("\nRecord no %d / %d",i+1,n);
printf("\nEnter book title & price: ");
scanf("%s %d",&b[i].title, &b[i].price);
}
show(b,n);
}
int main()
{
struct Book b[3];
get(b,3);
return 0;
}
Call sequence is like main() --> get() -->show(). I'm using Dev cpp compiler with .c extension of my code file.
title member of struct Book is just a pointer to char *, so when you define a struct Book structure, no memory has been allocated for its title.
Either define title as an array or allocate memory for it.
I'm trying to forward reference a (nested) structure, in C.
That means I have a structure and in it I'm referencing to another structure that is declared later.
If I declare the nested structure as a pointer, and initialize it with values, it works.
The following code works:
#include <stdio.h>
struct computer{
double cost;
int year;
char cpu_type[16];
struct cpu_speed *sp; //this is the question (1)
};
struct cpu_speed{
int num;
char type[16];
};
typedef struct computer SC;
typedef struct cpu_speed SS;
void DataR(SC *s);
void DataP(SC *s);
int main(){
// this is question (2)
SS speed = {4,"giga"};
SC model[2] = {
{ 0,1990, "intel", &speed},
{ 0,1990, "intel", &speed}
};
int i;
for(i=0;i<2;i++) {
printf("computer no. %d \n", i+1);
DataR(&model[i]);
}
printf("here's what you entered: \n");
for(i=0;i<2;i++) {
printf("computer no. %d \n", i+1);
DataP(&model[i]);
}
return 0;
}
void DataR(SC *s){
printf("the cost of your computer: ");
scanf("%lf", &s->cost);
printf("the year of your computer: ");
scanf("%d", &s->year);
printf("the type of cpu inside your computer: ");
scanf("%s", s->cpu_type);
printf("the speed of the cpu: ");
scanf("%d %s", &(s->sp->num), s->sp->type);
}
void DataP(SC *s){
printf("the cost: %.2lf\n",s->cost);
printf("the year: %d\n",s->year);
printf("the cpu type: %s\n",s->cpu_type);
printf("the cpu speed: %d %s\n",s->sp->num, s->sp->type);
}
If I declare the nested struct (i.e. struct cpu_speed{...};) before the parent(?) struct, I do not need to use a pointer, and I also don't need to initialize.
Meaning:
(1) I can use struct cpu_speed speed; instead of struct cpu_speed *sp;.
(2) I do not need to give initialized values to the structures variables.
My questions again - in forward referencing structure - (1) do you have to declare it with a pointer? and (2) do you have to initialize the values?
Structures are only used by the compiler to align your memory. Thus, it needs to know the size of struct members.
struct foo {
struct bar *pointer;
};
In this case, the sizeof(pointer) is unrelated to the bar struct and thus the compiler does not need to know anything more.
However, if you want to add the bar struct to the foo struct, it does need to know about its individual members.
struct bar {
const char *string;
uint64_t integer;
};
struct foo {
struct bar sub;
};
You need to declare the bar struct before foo because the compiler needs to know what you're referring to. Otherwise, how would it know what to do with this (illegal) code:
struct bar {
struct foo sub;
};
struct foo {
struct bar sub;
};
I have a question about passing function to another function which both have structure as arguments. First I created two structures:
typedef struct
{
char name[25],surname[25];int number;
}PLAYER;
typedef struct
{
char nameofteam[25];int numberofplayers;char *players;
}TEAM;
Then I defined a function to read elements of one player:
void readplayer(PLAYER *);
void readplayer(PLAYER *pi)
{
printf("name:");scanf("%s",pi->name);
printf("surname:");scanf("%s",pi->surname);
printf("number of player:");scanf("%d",&pi->number);
}
My question is how to create function which prototype is void readteam(TEAM*) which will read data for one team, but using function readplayer and call it in main()? Here is what I have tried:
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
char name[25],surname[25];int number;
}PLAYER;
typedef struct
{
char nameofteam[25];int numberofplayers;char *players;
}TEAM;
void readplayer(PLAYER *pi)
{
printf("name:");scanf("%s",pi->name);
printf("surname:");scanf("%s",pi->surname);
printf("number of player:");scanf("%d",&pi->number);
}
void readteam(TEAM *pt)
{
char players[101];int i;
printf("name of team:");scanf("%s",pt->nameofteam);
printf("number of players in team:");scanf("%d",&pt->numberofplayers);
printf("players:");scanf("%s",players);
pt->players=(char *)calloc(length(players)+1,sizeof(char));
copy(pt->players,players);
for(i=0;i<pt->numberofplayers;i++)
{
printf("%d.",i+1);
readplayer(pt+i);
}
}
void erase(TEAM *);
void erase(TEAM *pt)
{
free(pt->players);
}
int length(char *s)
{
int d=-1;
while(s[++d]);
return d;
}
void copy(char *s1,char *s2)
{
while(*s1++ = *s2++);
}
int main()
{
int i,n;
TEAM *p;
do
{
printf("n=");scanf("%d",&n);
}
while(n<1);
p=(TEAM *)malloc(n * sizeof(TEAM));
for(i=0;i<n;i++)
{
printf("%d.",i+1);readteam(p+i);
}
free(p);
}
This gives me an error at the last input (in compiling, not debugging). Must be because of inappropriate use of dynamic allocation. I didn't use <string.h library. Obviously, only the readteam function has to be in main().
Thanks for the answers.
You are confused on how to store the playsrs. You have created a PLAYER struct, but you never use it. Instead, you insist that players must be a single string.
But it should work like this: You have n teams. Ecah team has m players. All team info is stored in your ´TEAMstruct. All player info is stored in yourPLAYERstruct. Because a team is made up of players, there should be aPLAYER` entry in your struct:
typedef struct {
char name[25];
char surname[25];
int number;
} PLAYER;
typedef struct {
char nameofteam[25];
int numberofplayers;
PLAYER *players;
} TEAM;
Then, when you read players, you read the bare team info in readteam. But you don't read anything about individual players there, because you delegate that to readplayer. Of course, the pointer you pass to that function must be that for a player, not one for a team:
void readplayer(PLAYER * pi)
{
printf("name:");
scanf("%s", pi->name);
printf("surname:");
scanf("%s", pi->surname);
printf("number of player:");
scanf("%d", &pi->number);
}
void readteam(TEAM * pt)
{
int i;
printf("name of team:");
scanf("%s", pt->nameofteam);
printf("number of players in team:");
scanf("%d", &pt->numberofplayers);
pt->players = calloc(pt->numberofplayers, sizeof(*pt->players));
for (i = 0; i < pt->numberofplayers; i++) {
printf("Player %d:\n", i + 1);
readplayer(pt->players + i);
}
}
Your cast to (char *) hides the warning about incompatible types. You should cast only when you know what you're doing. In this simple program, you don't need casts.
In your original code, there are warnings about "implicit declarations". These concern your copy and length functions. (By the way, what's wrong with strlen and strcpy?) You should move these functions to the top so that they are declared before they are called. ALternatively, provide prototypes at the beginning of your code or in a header file, which you #include at the top. (But now that you read into PLAYER structs, these functions are no longer needed.)
my questions here always seem to be about using functions. It still confuses me! In this textbook exercise i am asked to pass a structure by value, then adjust it and pass by reference. Initially I designed the code to have everything done in main. Now I am passing by value. So I added the new function, and I figured I passed the structure correctly but I am getting an error at line
void function1(struct Inventory inv){ that tells me parameter 1 (inv) has incomplete type. please help!
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void function1(struct Inventory inv);
struct Inventory{
char name[20];
int number;
float price;
float total;
}
void main(){
items;
void function1(items);
float total = items.number*items.price;
printf("Item\tNumber\tPrice\tTotal\tAddress of number\n");
printf("%s\t%d\t%.2f\t%.2f\t%X\n\n",items.name,items.number,items.price,total,&items.number);
getch();
}
void function1(struct Inventory inv) {
printf("Enter the name of the item: ");
scanf("%s", inv.name);
printf("Enter the number of items: ");
scanf("%d", &inv.number);
printf("Enter the price of each item: ");
scanf("%f", &inv.price);
}
You have to define your struct BEFORE you use it in your function prototype.
struct Inventory{
char name[20];
int number;
float price;
float total;
}items;
void function1(struct Inventory inv);
while compiling i am having an error: expected ) and ( in c for the following program:
#include<stdio.h>
#include<conio.h>
struct student
{
char name[20];
int rollno;
int age;
char classes[10];
};
void printdata(struct student &sob); //getting error in this line
void main()
{
struct student stud;
clrscr();
printf("enter student details:");
printf("\nenter student name:"); fflush(stdin);
gets(stud.name);
printf("\nenter age:");
scanf("%d",&stud.age);
printf("\nenter rollno:");
scanf("%d",&stud.rollno);
printf("\nenter class of student:"); fflush(stdin);
gets(stud.claases);
printdata( &stud);
getch();
}
void printdata(struct student &sob) //getting error in this line
{
struct student *ptr;
ptr=sob;
printf("student details are as follows:");
printf("\nstudent's name:"); fflush(stdout);
puts(ptr->name);
printf("\n student' age:%d",ptr->age);
printf("\n student's roll no:%d",ptr->rollno);
printf("\n student's class:"); fflush(stdout);
puts(ptr->classes);
}
it is that i have already declared the structure student then why is it giving me the error ( and ) in two lines..
struct student & is not valid C. It appears to be C++ code.
void main() is not valid C (unless the program is a free standing one, which this one clearly is not).
The gets() function has been removed from the C language as per the C11 standard.
fflush(stdin) is undefined behavior.
Unrelated, your code is difficult to read. Make a habit of adding some empty lines between different functions and declarations.
Unrelated, it appears that you are using Turbo C for DOS or something equally bad and non-standard. Don't use such old crap compilers, using a bad compiler is one source for all these problems.
You made a typo :
gets(std.claases); // it's std.classes
And the printdata() param should be "struct student *sob".
This solution should works :
#include <stdio.h>
struct student {
char name[20];
int rollno;
int age;
char classes[10];
};
void printdata(struct student *sob);
int main(void) {
struct student stud;
printf("enter student details:");
printf("\nenter student name:");
fflush(stdin);
gets(stud.name);
printf("\nenter age:");
scanf("%d", &stud.age);
printf("\nenter rollno:");
scanf("%d", &stud.rollno);
printf("\nenter class of student:");
fflush(stdin);
gets(stud.classes);
printdata(&stud);
return 0;
}
void printdata(struct student *sob)
{
struct student *ptr;
ptr = sob;
printf("student details are as follows:");
printf("\nstudent's name:");
fflush(stdout);
puts(ptr->name);
printf("\n student' age:%d", ptr->age);
printf("\n student's roll no:%d", ptr->rollno);
printf("\n student's class:");
fflush(stdout);
puts(ptr->classes);
}
BTW, the main function must return an integer, it's a standard.
Your function printData should accept a pointer struct student *ob not struct student &ob.
There's no reference in C (like in C++). Change the function prototype and defintion to take pointers as argument.
Change
void printdata(struct student &sob); //getting error in this line
to
void printdata(struct student *sob); //getting error in this line
and change
void printdata(struct student &sob) //getting error in this line
to
void printdata(struct student *sob) //getting error in this line
Other problems are:
You have misspelled a member name: gets(stud.claases); should be: gets(stud.classes);
Don't use gets(). Use fgets() instead as gets() isn unsafe and cause buffer overflow issue.
fflush(stdin); is undefined behaviour in C.