Error in using typedef - c

I have this code in c-
This is my Room.h file
typedef int Room[10][10];
THis is my main code-
#include"Room.h"
#include<stdio.h>
#include<stdlib.h>
int createRoom(Room * pm,char *filename)
{
FILE * input;FILE * output;
input=fopen(filename,"r");
int a;int i=0,j=0;int count;
fscanf(input,"%d",&a);
while(!feof(input))
{
pm[i][j]=a; // incompatible types when assigning to type ‘int[10]’ from type ‘int’
i++;j++;count++;
fscanf (input, "%d", &a);
}
for(i=0;i<count;i++)
{
for(j=0;j<count;j++)
printf("%d ",pm[i][j]);
printf("\n");
}
fclose(input);
return count;
}
int main()
{
char name[100];
printf("Enter file name\n");
scanf("%s",name);
Room *pm;
//pm=malloc(sizeof(Maze ));
int n=createRoom(pm,name);
return 0;
}
I get this error- incompatible types when assigning to type ‘int[10]’ from type ‘int’ in this line-pm[i][j]=a; .Why is it so?

This line
pm[i][j]=a;
needs to be changed to
(*pm)[i][j]=a;
More importantly, your code does not allocate memory for pm. In main, you have:
Room *pm;
//pm=malloc(sizeof(Maze ));
int n=createRoom(pm,name);
I wonder why you removed the line to allocate memory for pm. You can use:
Room *pm;
pm=malloc(sizeof(*pm));
int n=createRoom(pm,name);
and make sure to deallocate memory.
free(pm);
Or, you could just use:
Room pm;
int n=createRoom(&pm,name);

Related

passing 'person [4]' to parameter of incompatible type 'person'

Here I'm trying to write a c programming below,Here I created a data type person which has two arguments name and number (creating a name of the candidate and votes they have recieved), and when prompt for input,if user enters the name in the array of person data_type and number corresponds to that number should increase,but I got stuck in this error below.
#include<stdio.h>
#include<cs50.h>
#include<string.h>
//Making person variable
typedef struct
{
string name;
int number;
}
person;
int update_vote(string name,person arr);
int main(void)
{
person cand[4];
cand[0].name="Brian";
cand[1].name="David";
cand[2].name="Obama";
cand[3].name="Biden";
cand[0].number=0;
cand[1].number=0;
cand[2].number=0;
cand[3].number=0;
//print the candidate names on the screen
float len=sizeof(cand)/sizeof(cand[0]);
int yu =(int) len;
printf("Candidates Who are participating:");
printf("\n");
for (int i=0;i<yu;i++)
{
printf("%i.%s ",i+1,cand[i].name);
}
printf("\n");
//prompt for voters and take votes and update
int voters=get_int("Enter the number of voters:");
for (int j=0;j<voters;j++)
{
string vote=get_string("Enter your vote:");
int update=update_vote(vote,cand);
if (update!=-1)
{
cand[update].number++;
}
else{
printf("Invalid name entered");
}
}
printf("%d",cand);
}
int update_vote(string name,person arr)
{
float len=sizeof(arr)/sizeof(arr[0]);
int yu =(int) len;
for(int i=0;i<yu;i++)
{
if (strcmp((name,arr[i].name)==0))
{
return i;
}
}
return -1;
}
But got stuck in figuring out why the error is occuring below
error: passing 'person [4]' to parameter of incompatible type 'person'
int update=update_vote(vote,cand);
The error is because you are passing person* where person is expected as an argument.
You should change the type of argument so that it can receive (a pointer to) an array.
Also note that sizeof cannot be used to determing the number of elements of arrays passed as arguments. You should pass the number of elements separately.
Another point is that printf("%d",cand); will invoke undefined behavior because data having wrong type is passed. %d expects int. If you want to print a pointer, you should cast it to void* and use %p format specifier.
Try this:
#include<stdio.h>
#include<cs50.h>
#include<string.h>
//Making person variable
typedef struct
{
string name;
int number;
}
person;
int update_vote(string name,person* arr,int arrSize); /* fix arguments */
int main(void)
{
person cand[4];
cand[0].name="Brian";
cand[1].name="David";
cand[2].name="Obama";
cand[3].name="Biden";
cand[0].number=0;
cand[1].number=0;
cand[2].number=0;
cand[3].number=0;
//print the candidate names on the screen
float len=sizeof(cand)/sizeof(cand[0]);
int yu =(int) len;
printf("Candidates Who are participating:");
printf("\n");
for (int i=0;i<yu;i++)
{
printf("%i.%s ",i+1,cand[i].name);
}
printf("\n");
//prompt for voters and take votes and update
int voters=get_int("Enter the number of voters:");
for (int j=0;j<voters;j++)
{
string vote=get_string("Enter your vote:");
int update=update_vote(vote,cand,yu); /* pass the number of elements */
if (update!=-1)
{
cand[update].number++;
}
else{
printf("Invalid name entered");
}
}
printf("%p",(void*)cand); /* use correct way to print a pointer */
}
int update_vote(string name,person* arr,int arrSize) /* fix arguments */
{
int yu =arrSize; /* use the passed size instead of sizeof */
for(int i=0;i<yu;i++)
{
if (strcmp((name,arr[i].name)==0))
{
return i;
}
}
return -1;
}
Because person cand[4]; , when you use " int update=update_vote(vote,cand);" , it means 'person *' that it's pointer.

How do I pass an array of structures to a function?

I'm trying to pass an array of structs to a function which fills them with data.
When I try to compile the code I am told that there is an error:
In function 'main':
error: expected expression before 'Robot_t'
loading_Profiles (Robot_t RobotInfo[]);
I am not sure what I am missing?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
typedef struct {
int Robot_Number;
char Robot_Name[30];
int Year_Manufacturer;
float Top_Speed;
float Mass;
float Best_Score;
} Robot_t;
void loading_Profiles();
int main()
{
Robot_t RobotInfo[5];
loading_Profiles (Robot_t RobotInfo[]);
int i;
for (i = 0; i < 50; i++) {
printf("%d\t\t%s\t\t%d\t\t\t%.2f\t\t%.2f\t\t%.2f\n",
RobotInfo[i].Robot_Number, RobotInfo[i].Robot_Name,
RobotInfo[i].Year_Manufacturer, RobotInfo[i].Top_Speed,
RobotInfo[i].Mass, RobotInfo[i].Best_Score);
}
return 0;
}
void loading_Profiles()
{
int Counter = 0;
int i;
Robot_t RobotInfo[5];
FILE *ROBOTtxt = fopen("Robot.txt", "r");
if (ROBOTtxt == NULL) {
perror("an error occured during the loading of the file\n");
exit(-1);
}
for (i = 0; i < 50; i++) {
char LineNumber[100] = "";
fgets(LineNumber, 100, ROBOTtxt);
sscanf(LineNumber, "%d %s %d %f %f %f",
&RobotInfo[i].Robot_Number,
RobotInfo[i].Robot_Name,
&RobotInfo[i].Year_Manufacturer,
&RobotInfo[i].Top_Speed,
&RobotInfo[i].Mass,
&RobotInfo[i].Best_Score);
Counter++;
if (feof(ROBOTtxt)) {
break;
}
}
if (ferror(ROBOTtxt)) {
perror("an error has occured");
exit(-1);
}
fclose(ROBOTtxt);
}
There are several issues with your program. The obvious one is that your function prototypes do not match:
void loading_Profiles()
should be
void loading_Profiles(Robot_t *robots)
in both the declaration and definition.
The array Robot_t RobotInfo[5] in main, and the Robot_t RobotInfo[5] in loading_Profiles do not refer to the same array. They are separate arrays, local to each function. You need to pass the array from main to the loading_Profiles function, which should then modify the array.
Your code also contains various size errors. You are defining an array of 5 elements, and then trying to read and write up to 50 elements. Beyond the mismatch, you need to think about what happens if your file contains less lines than expected.
Counter is unused. As are the return values of some functions that can indicate status / errors:
fgets already partially indicates if it has reached EOF by returning NULL.
sscanf returns the numbers of conversions that took place, which can be used to make sure a partial set of data wasn't stored.
Here is a rewritten example that showcases how to pass arrays around, fill them to a maximum, and utilize the return values of stdio functions. Notice how the type signature of load_robot_profiles matches exactly between the declaration, definition, and invocation of the function.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int number;
char name[32];
int year_manufactured;
float top_speed;
float mass;
float best_score;
} Robot;
size_t load_robot_profiles(Robot *, size_t, const char *);
int main(void) {
Robot robots[5];
size_t length = load_robot_profiles(robots, 5, "robots.txt");
for (size_t i = 0; i < length; i++) {
Robot *r = &robots[i];
printf("%d\t%s\t%d\t\t%.2f\t%.2f\t%.2f\n",
r->number, r->name, r->year_manufactured,
r->top_speed, r->mass, r->best_score);
}
}
size_t load_robot_profiles(Robot *robots, size_t size, const char *fname) {
size_t i = 0;
FILE *file = fopen(fname, "r");
char input[128];
if (!file)
return 0;
while (i < size && fgets(input, sizeof input, file)) {
Robot *r = &robots[i];
if (6 == sscanf(input, "%d %s %d %f %f %f",
&r->number, r->name, &r->year_manufactured,
&r->top_speed, &r->mass, &r->best_score))
i++;
}
fclose(file);
return i;
}
Also note: Defining a type with a _t suffix is ill-advised, as eventually you will brush up against a conflict with an existing POSIX type, or other standard.
Your definition and declaration of the function void loading_Profiles() don't include any arguments, but you're calling it with an argument: loading_Profiles (Robot_t RobotInfo[]);.
You need to change the function to accept Robot_t RobotInfo[] as an argument and then modify the RobotInfo[] array.
The function signature should be like that:
void loading_Profiles(Robot_t* RobotInfo);
Also, there is no need to redeclare the Robot_t RobotInfo[5] inside your loading_Profiles function, since it is already passed by the function call.

Struct initialized in function loses values (although it's an array)

I'm trying to initialize array *dip inside "leggif1", inside it if you do a print it's all normal but if you try to print in the main, after the initialization, everything loses its values.
Same thing happen with ADT of first grade "Divisione" and i can't understand why (even though they are passed "by reference" thanks to their pointers).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int matricola;
char nome[20+1],cognome[20+1];
int comp[4];
}dipendente;
typedef struct divisione *Divisione;
struct divisione{
dipendente *dip;
char nome[10+1];
int terna[4][3]; //numero minimo di addetti,competenza minima totale, competenza ottimale totale
//per ognuna delle 4 tipologie
};
void leggif1(dipendente *dip, char *filename);
int leggif2(Divisione *Div, char *filename);
void DIVstampa(Divisione *Div,char *filename,int D);
Divisione DIVinit();
void DIVfree(Divisione *Div);
int main(int argc,char **argv) {
dipendente *dip;
Divisione *Div;
leggif1(dip,argv[1]);
int D=leggif2(Div, argv[2]);
DIVstampa(Div,"stdout",D);
return 0;
}
void leggif1(dipendente *dip, char *filename) {
FILE *fp=fopen(filename,"r");
int i,N;
fscanf(fp,"%d",&N);
dip=malloc(N*sizeof(dipendente));
for(i=0;i<N;i++)
fscanf(fp,"%d %s %s %d %d %d %d",&dip[i].matricola,dip[i].nome,dip[i].cognome,
&dip[i].comp[0],&dip[i].comp[1],&dip[i].comp[2],&dip[i].comp[3]);
}
int leggif2(Divisione *Div, char *filename) {
FILE *fp=fopen(filename,"r");
int i,j,D;
fscanf(fp,"%d",&D);
Div=malloc(D*sizeof(Divisione));
for(i=0;i<D;i++)
Div[i]=DIVinit();
for(i=0;i<D;i++) {
fscanf(fp, "%s", Div[i]->nome);
for (j = 0; j < 4; j++)
fscanf(fp, "%d %d %d", &Div[i]->terna[j][0], &Div[i]->terna[j][1], &Div[i]->terna[j][2]);
}
return D;
}
void DIVstampa(Divisione *Div, char *filename, int D) {
FILE *fp;
if(strcmp(filename,"stdout")==0)
fp=stdout;
else
fp=fopen(filename,"w");
int i,j;
for(i=0;i<D;i++) {
fprintf(fp,"%s\n", Div[i]->nome);
for(j=0;j<4;j++)
fprintf(fp,"%d %d %d\n", Div[i]->terna[j][0], Div[i]->terna[j][1], Div[i]->terna[j][2]);
}
}
Divisione DIVinit(){
Divisione Div=malloc(sizeof (*Div));
return Div;
}
void DIVfree(Divisione *Div){
free(Div);
}
The leggif1 function ignores the value of dip and assigns it a new value. That value is never returned to main.
The type of dip is dipendente* and when called in main the value of the pointer is passed to the function. Overwriting that local copy in the function does not affect the value of the pointer in main.
C only has 'call by value', always make sure you known what that value represents.
This can be solved by returning the dip from the function instead of taking it as a parameter:
dipendente* leggif1(char *filename)
{
//open file and read N
dipendente *dip = malloc(N * sizeof *dip);
if (!dip) {
return NULL;
}
// read in the data
return dip;
}
another way is to use a dipendente** (a pointer to a pointer) but that would, in this case, make the code needlessly complex.
The leggif2 function has the same problem.

Incompatible pointer type when making structure of function pointers

I'm trying to make a array of structures which contain a string and a function pointer, however when I compile I get a warning that I've initialized from an incompatible pointer type.
I have no idea why (sorry if I sound ignorant, I'm fairly new to C programming).
typedef struct
{
char Player1[2], Player[2], **gameGrid;
int height,width;
int moveNum, player1Num, player2Num;
bool player1Win, player2Win;
}Game;
typedef int (*pointer_func)(Game *);
typedef struct
{
char *funcName;
pointer_func *f;
}userFunc;
int save(Game *struc);
int load(Game *struc);
int move(Game *struc);
int quit(Game *struc);
void free_grid(Game *struc);
int main(){
//initialised variables
userFunc Name_arr[] = {
{"save",save},
{"load",load},
{"quit",quit},
{"move",move}
};
The four functions being referenced are as follows:
int save(Game *struc)
{
char *str, *inputString, *writeString;
FILE *fp;
int nextPlayer;
int maxRead = 20;
bool DIRresponse;
while(true)
{
printf("Please provide a file name (20 characters max): ");
inputString = input_String(inputString, maxRead, stdin);
if((DIRresponse = check_Directory(inputString)) == true){
printf("That name already exists, choose another\n");
continue;
}
else
break;
}
if(struc->moveNum % 2 == 0)
nextPlayer = struc->player1Num;
else
nextPlayer = struc->player2Num;
sprintf(str,"%s.txt",inputString);
fp = fopen(str,"w");
sprintf(writeString, "%d %d %d %d %d", nextPlayer, struc->height,
struc->width, struc->moveNum, struc->moveNum);
fprintf(fp,writeString);
fclose(fp);
return 0;
}
int move(Game *struc)
{
return 1;
}
int load(Game *struc)
{
return 1;
}
int quit(Game *struc)
{
free_grid(struc);
exit(EXIT_SUCCESS);
}
You have a mismatch in levels of pointers:
typedef int (*pointer_func)(Game *); << Pointer type
typedef struct
{
char *funcName;
pointer_func *f; << Pointer to a pointer type.... OOPS
}userFunc;
Make *f -> f and it should work.

Why am I getting garbage value after displaying the data

I am getting garbage value when I display the records.
I have to create a database of students in C using array of structures and without pointers.
Is there any other way of doing this?
How to use array of structures?
#include <stdio.h>
struct student {
char first_name[10],last_name[10];
int roll;
char address[20];
float marks;
};
void accept(struct student);
void display(struct student);
void main() {
struct student S[10];
int n, i;
printf("Enter the number of records to enter : ");
scanf("%d", &n);
for (i = 0; i < n; i++) {
accept(S[i]);
}
for (i = 0; i < n; i++) {
display(S[i]);
}
}
void accept(struct student S) {
scanf("%s", S.first_name);
scanf("%s", S.last_name);
scanf("%d", &S.roll);
scanf("%s", S.address);
scanf("%f", &S.marks);
}
void display(struct student S) {
printf("\n%s", S.first_name);
printf("\n%s", S.last_name);
printf("\n%d", S.roll);
printf("\n%s", S.address);
}
Everything in C is pass-by-value. Which means you are modifying variable copy in stack frame, while real variable passed as parameter remains untouched.
You have to pass an pointer to variable which you want to modify in function.
// Function declaration
void accept(struct student *);
// Call
accept(&S[i]);
// Usage in function via dereference operator
scanf("%s",S->first_name);
If you would like to enter unknown amount of records, you should use VLA (since c99) or dynamically allocate structures.
VLA
scanf("%d",&n);
struct student S[n];
Dynamic callocation
scanf("%d",&n);
struct student * S = malloc(sizeof(struct student) * n);
Because in your case, if user input more that 9 records you are touching outside of bounds, which has undefined behavior.
There are multiple issues in your code:
The standard prototype for main without arguments is int main(void)
You should allocate the array dynamically with calloc.
you should pass structure pointers to the accept and display functions instead of passing structures by value. Passing the destination structure by value is incorrect as the accept function cannot modify the structure in the main function, which remains uninitialized and causes garbage to be displayed. Note that it is actually undefined behavior to access uninitialized data so the program could behave in even worse ways.
You should provide scanf() with the maximum number of arguments to store into character arrays to avoid potential buffer overflows.
you should verify the return values of scanf() to avoid undefined behavior on invalid input.
you could use the %[^\n] scan set to allow embedded spaces in the address field.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
struct student {
char first_name[10], last_name[10];
int roll;
char address[20];
float marks;
};
void accept(struct student *sp);
void display(const struct student *sp);
int main(void) {
struct student *S;
int n, i, j;
printf("Enter the number of records to enter : ");
if (scanf("%d", &n) != 1)
return 1;
S = calloc(sizeof(*S), n);
if (S == NULL) {
return 1;
}
for (i = 0; i < n; i++) {
accept(&S[i]);
}
for (i = 0; i < n; i++) {
display(&S[i]);
}
free(S);
return 0;
}
void accept(struct student *sp) {
if (scanf("%9s%9s&d %19[^\n]%f",
sp->first_name, sp->last_name, &sp->roll,
sp->address, &sp->marks) != 5) {
printf("missing input\n");
exit(1);
}
}
void display(const struct student *sp) {
printf("%s\n", sp->first_name);
printf("%s\n", sp->last_name);
printf("%d\n", sp->roll);
printf("%s\n", sp->address);
printf("%f\n", sp->marks);
printf("\n");
}

Resources