I am trying to create an array of structs and create functions to manipulate it. Errors: "expected expression before '{' token" and "too few arguments to function 'SDB_AddEntry'
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef unsigned char uint8;
typedef struct
{
uint8 studentID;
uint8 studentYear;
uint8 subjectIDs[3];
uint8 grades[3];
bool structCreated;
}Entry;
Entry database[10];
uint8 SDB_GetUsedSize(Entry database[])
{
for(uint8 i=0;i<10;i )
{
if(database[i].structCreated==false)
return i;
}
return 10;
}
bool SDB_AddEntry(Entry database[], uint8 id, uint8 year, uint8* subjects, uint8* grades)
{
Entry e = {id, year, subjects, grades, true};
if(SDB_GetUsedSize(database)==9)
return false;
else
{
database[SDB_GetUsedSize(database) 1] = e;
return true;
}
}
int main()
{
SDB_AddEntry(database, 2, 60, {2,4,3}, {97,86,90});
printf("%d",database[0].structCreated);
return 0;
}
I also tried
Entry *database
instead of
Entry database[]
in function declaration but it did not work (same errors).
Previously I tried to use a pointer to the array of structs and pass that to the functions but I could not work out how to use it properly.
CodePudding user response:
You can not pass arrays in this way:
SDB_AddEntry(database, 2, 60, {2,4,3}, {97,86,90});
instead, use compound literals:
SDB_AddEntry(database, 2, 60, (uint8[]){2,4,3}, (uint8[]){97,86,90});
Also switch to pointers:
typedef struct
{
...
uint8 subjectIDs[3];
uint8 grades[3];
...
}Entry;
should be
typedef struct
{
...
uint8 *subjectIDs;
uint8 *grades;
...
}Entry;
And change:
database[SDB_GetUsedSize(database) 1] = e;
to:
database[SDB_GetUsedSize(database)] = e;
Otherwise it won't work: if you use array_size 1 you will skip 1 position every time and can eventually exceed the array size.
CodePudding user response:
The first thing to note is that the database is defined globally. If this is intended, and there is only one, there's no need to be passing its location to the support functions. (In fact, that can be a potential source of bugs.)
Next, the problem seems to be the syntax for creating an unnamed Entry struct on the stack. If you change the struct declaration, every instance of add()
in the source code will have to be found and adapted.
I offer the following as an alternative approach to solving the problem. Just as in your OP, each of up to 4 'records' is initialised at compile time. Perhaps you can see how to adapt this to an interactive solution (or reading records from a file.)
typedef unsigned char uint8;
typedef struct {
uint8 studentID; // non-zero ID means record is used.
uint8 studentYear;
uint8 subjectIDs[3];
uint8 grades[3];
} Entry;
Entry db[10] = {
{ 2, 60, {2,4,3}, {97,86,90} },
{ 3, 61, {2,4,3}, {97,86,90} },
};
int dbSize = sizeof db / sizeof db[0];
uint8 SDB_GetUsedSize() {
for( uint8 i = 0; i < dbSize && db[i].studentID; i ) {}
return i;
}
bool SDB_AddEntry( Entry *e ){
int ind = SDB_GetUsedSize();
if( ind == dbSize )
return false;
db[ ind ] = e; // new compiler struct copy
// memcpy( &db[ ind ], e, sizeof db[0] ); // old compiler fallback
return true;
}
void display() {
for( int i = 0; i < dbSize && db[i].studentID; i )
printf("#%d: ID = %d\n", i, db[i].studentID );
printf( "\n" );
}
int main() {
display();
{
Entry e = { 4, 62, {2,4,3}, {97,86,90} };
SDB_AddEntry( &e );
}
display();
{
Entry e = { 5, 63, {2,4,3}, {97,86,90} };
SDB_AddEntry( &e );
}
display();
return 0;
}