Whys is here i am unable to print the info? - c

the console is showing the following when I am trying to run it. can someone tell me how to fix it:
arrow.c:3:23: warning: 'struct student' declared inside parameter list will not be visible outside of this definition or declaration
void printInfo(struct student s1);
^~~~~~~
arrow.c: In function 'main':
arrow.c:13:15: error: type of formal parameter 1 is incomplete
printInfo(s1);
^~
arrow.c: At top level:
arrow.c:18:6: error: conflicting types for 'printInfo'
void printInfo(struct student s1){
^~~~~~~~~
arrow.c:3:6: note: previous declaration of 'printInfo' was here
void printInfo(struct student s1);
void printInfo(struct student s1);
struct student {
int roll;
float cgpa;
char name[100];
};
int main(){
struct student s1 = {1664, 9.2, "shradha"};
printInfo(s1);
return 0;
}
void printInfo(struct student s1){
printf("student information ; \n");
printf("student.roll = %d\n", s1.roll);
printf("student.name = %s\n", s1.name);
printf("student.cgpa = %f \n ", s1.cgpa);
s1.roll = 4558;
}

formal parameter 1 is incomplete
As soon as you reference anything where its size is required to be known by the compiler, you must have shown the compiler its definition. In your case it's just a matter of reorganizing the declarations and definitions:
#include <stdio.h>
struct student {
int roll;
float cgpa;
char name[100];
};
// struct student is now defined and ok to take by value in this
// forward declaration:
void printInfo(struct student s1);
int main(void) {
struct student s1 = {1664, 9.2, "shradha"};
printInfo(s1);
}
void printInfo(struct student s1) {
printf("student information ; \n");
printf("student.roll = %d\n", s1.roll);
printf("student.name = %s\n", s1.name);
printf("student.cgpa = %f \n ", s1.cgpa);
s1.roll = 4558;
}
Note: if printInfo had taken a struct student* instead, the size of a struct student would not need to be known since the size of a pointer is already known and is the same for all objects. This would also make the assignment of roll useful.
Example:
#include <stdio.h>
struct student;
void printInfo(struct student *s1);
struct student {
int roll;
float cgpa;
char name[100];
};
int main(void) {
struct student s1 = {1664, 9.2, "shradha"};
printInfo(&s1);
printf("now visible at the call site: %d\n", s1.roll); // prints 4558
}
void printInfo(struct student *s1){
printf("student information ; \n");
printf("student.roll = %d\n", s1->roll);
printf("student.name = %s\n", s1->name);
printf("student.cgpa = %f\n", s1->cgpa);
s1->roll = 4558;
}

Related

Error initializing structures with helper function

#include <stdio.h>
int j=0;
struct student
{
int CNE;
char Nom[20];
char Prenom[20];
char Ville[20];
float Note[3];
float Moyenne;
};
void read_struct(struct student stu)
{
stu.Moyenne=0;
printf("Nom de l'etudiant:\t ");
scanf(" %s",stu.Nom);
printf("Prenom de l'etudiant:\t ");
scanf(" %s",stu.Prenom);
printf("CNE de l'etudiant:\t ");
scanf("%d",&stu.CNE);
}
int main()
{
struct student stu[10];
read_struct(stu[0]);
read_struct(stu[1]);
printf("%s \n %s \n",stu[0].Nom,stu[1].Nom);
printf("%d \n %d",stu[0].CNE,stu[1].CNE);
}
I m getting some weird output after compiling, the input from users are not saved in struct after calling them back.( sorry for my english)
Look at how this function is defined:
void read_struct(struct student stu) {
...
}
When you call this function, it passes in a copy of the struct student, so the function does its work to fill in the copy rather than the original.
You may want to have this function take in a pointer to the struct student:
void read_struct(struct student* stu) {
/* You'll need to change things here */
}
read_student(&stu[0]);
read_student(&stu[1]);
Hope this helps!

How to fill in values in struct using a function?

I want to call a function to fill in the values of a struct in C. I have the following code but I get errors like [Error] request for member 'id' in something not a structure or union.
#include <stdio.h>
typedef struct {
int id;
float grades[3];
} student_t;
void scan_student (student_t *s) {
printf("Please give student's info:\n");
scanf("%d%f%f%f", s.id, s.grades[0], s.grades[1], s.grades[2]);
}
int main ()
{
student_t stu2;
scan_student(&stu2);
printf("Student's info are:\n");
printf("%6d %5.2f %5.2f %5.2f\n", stu2.id, stu2.grades[0], stu2.grades[1], stu2.grades[2]);
return 0;
}
s is a pointer, not a struct. That means you can't use . on it.
Instead you have to write (*s).id (dereference, then access struct member) or s->id (same thing, but shorter).
Also, scanf %d takes a pointer, so that should be &s->id, etc.
I also post an example without using pointers:
#include <stdio.h>
typedef struct {
int id;
float grades[3];
} student_t;
student_t scan_student () {
student_t s;
printf("Please give patient's info:\n");
scanf("%d%f%f%f", &s.id, &s.grades[0], &s.grades[1], &s.grades[2]);
return s;
}
int main ()
{
student_t stu2;
stu2= scan_student();
printf("Student's info are:\n");
printf("%6d %5.2f %5.2f %5.2f\n", stu2.id, stu2.grades[0], stu2.grades[1], stu2.grades[2]);
return 0;
}

C forward-referencing structures - 1) must be with a pointer? 2) must be initialized?

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;
};

bsearch failed to find string member in an array of structure

Using bsearch in C failed to find a string 'Eva Lam' in an array of structure. This array is sorted in descending order of string members. I checked many times, still don't know where the bug is? BTW, I am using DEV C++ 5.9.4. Please help, many thanks.
#include <stdio.h>
#include <stdlib.h> // for bsearch
#include <string.h>
#define SIZE 4
#define NAME_SIZE 20
struct student {
int id;
char name[NAME_SIZE];
};
// Function prototypes
int comp_name(const void* a, const void* b);
void print_struct_array(struct student studs[], int size, int serial);
int main(){
int i, option=0;
struct student *stud, *target;
// studs array already sort in descending order of name
struct student studs[SIZE] = {{14123456, "Mary Chan"}
, {11001234, "Eva Lam"}
, {10123456, "David Wong"}
, {12345678, "Chris So"}
};
printf("*** Before Searching ***\n");
print_struct_array(studs, SIZE, 1);
target = (struct student*) malloc(sizeof(struct student));
if (target == NULL) {
fprintf(stderr, "Out of memory!\n");
return -1;
}
printf("Input student name to search: ");
scanf("%[^\n]", target->name);
fflush(stdin);
printf("name=%s\n", target->name);
stud = (struct student *)bsearch(target->name, studs, SIZE,
sizeof(struct student), comp_name);
if (!stud)
printf("name %s not found!\n", target->name);
else
printf("[id, name] found is [%d, %s]\n", stud->id, stud->name);
return 0;
}
int comp_name(const void* a, const void* b) {
printf("comp_name: a->name=%s, b->name=%s\n",
(*(struct student *)a).name, (*(struct student *)b).name);
return strcmp((*(struct student *)b).name,
(*(struct student *)a).name);
}
void print_struct_array(struct student studs[], int size, int serial) {
int i;
printf("Student array #%d is {\n", serial);
for (i=0; i<SIZE; i++) {
if (i==0)
printf(" ");
else if (i<=SIZE-1)
printf(", ");
printf("[%d, %s]\n", studs[i].id, studs[i].name);
}
printf("}\n");
}
But the output of the program when searching 'Eva Lam' is:
*** Before Searching ***
Student array #1 is {
[14123456, Mary Chan]
, [11001234, Eva Lam]
, [10123456, David Wong]
, [12345678, Chris So]
}
Input student name to search: Eva Lam
name=Eva Lam
comp_name: a->name=Lam, b->name=Eva Lam
comp_name: a->name=Lam, b->name=Mary Chan
name Eva Lam not found!
--------------------------------
Process exited after 8.216 seconds with return value 0
Read the documentation for bsearch more carefully.
The compar routine is expected to have two arguments which point to the key object and to an array member, in that order.
This means that the first argument to your compare function will always be exactly what you gave as a first argument to bsearch. So either call it as: bsearch(target, studs, ...) or better yet, rewrite your compare function to:
int
comp_name(const void *av, const void *bv) {
const char *a = av;
const struct student *b = bv;
printf("comp_name: a->name=%s, b->name=%s\n", a, b->name);
return strcmp(b->name, a);
}
Also, please don't cast void * pointers in C, especially from malloc, but also the return value from bsearch in your code.

C program football team structure with pointer elements and dynamic allocation

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.)

Resources