Search code examples
cstructtypedef

I am getting this error, "error: expected expression before '{' token". I don't know why ? syntax looks fine to me


/*Using structures, write an interactive C program to 
generate Grade Card for BCA first semester courses for
20 students of your study centre.*/

#include<stdio.h>

struct Marks
{
    char subject[5];
    float subject_marks[5];
};

struct GradeCard
{
    char name[30];
    int roll_num;
    struct Marks table;

}; 
int main()
{
struct GradeCard student;
int i;

//name of student
printf("Enter the name of student: \t");
scanf("%s", &student.name);

//roll number of student
printf("Enter the roll number of student: \t");
scanf("%d", &student.roll_num);

//name of courses
printf("Enter the subjects: \t");
student.table.subject[5] = {'B', 'C', 'D', 'E', 'F'};

//marks in respective courses
for (i = 0; i < 5; i++)
{
    scanf("%f", &student.table.subject_marks[i]);
}

//printing all the details
printf("%s\n", student.name);
printf("%d\n", student.roll_num);
for(i = 0; i < 5; i++)
{
    printf("%s : %f\n",student.table.subject[i], student.table.subject_marks[i]);
}

}

I have to do this for 20 students. I want to try it with one student first. The error I am getting is this:

error: expected expression before '{' token
student.table.subject[5] = {'B', 'C', 'D', 'E', 'F'};


Solution

  • For this line:

    student.table.subject[5] = {'B', 'C', 'D', 'E', 'F'};
    

    I guess that OP thinks that the line assigns values to all the elements of the array student.table.subject[5] in the same way that char subject[5] = {'B', 'C', 'D', 'E', 'F'}; initializes all elements of the array subject[5]. They may look similar, but an assignment is not the same as an initialization.

    There are some problems with the assignment attempted above. :-

    Problem 1: {'B', 'C', 'D', 'E', 'F'} on the right side of an assignment expression is not a value of any type. It could be turned into a value of type char [5] by changing it into a compound literal. (char [5]){'B', 'C', 'D', 'E', 'F'} is a compound literal of type char [5]; it could also be written as (char []){'B', 'C', 'D', 'E', 'F'} where the number of elements is determined by the number of initializers between the braces. It is an unnamed array object.

    Problem 2: In most expressions, a value of an array type is converted into a pointer to the first element of the array and is no longer an lvalue. The left hand operand of the assignment operator = must be an lvalue. Therefore, the left hand operand of the assignment operator cannot be an array.

    There are various ways to solve OP's problem. :-

    Solution 1: Use memcpy to copy the values from another array:

    static const char subjects[5] = {'B', 'C', 'D', 'E', 'F'};
    memcpy(student.table.subject, subjects, 5);
    

    or:

    memcpy(student.table.subject, (char [5]){'B', 'C', 'D', 'E', 'F'}, 5);
    

    (Note: That makes use of a compound literal containing the source array contents to be copied to the destination.)

    or:

    memcpy(student.table.subject, "BCDEF", 5);
    

    (Note: "BCDEF" is just being used for convenience there. It has type char [6] including the null terminator, but only the first 5 elements are being copied.)

    Solution 2: Use a for loop to copy the values from another array:

    static const char subjects[5] = {'B', 'C', 'D', 'E', 'F'};
    
    for (i = 0; i < 5; i++)
    {
        student.table.subject[i] = subjects[i];
    }
    

    or:

    for (i = 0; i < 5; i++)
    {
        student.table.subject[i] = ((char []){''B', 'C', 'D', 'E', 'F'})[i];
    }
    

    or:

    for (i = 0; i < 5; i++)
    {
        student.table.subject[i] = "BCDEF"[i];
    }
    

    Solution 3: Assign to each element of the array using a linear sequence of statements:

    student.table.subject[0] = 'B';
    student.table.subject[1] = 'C';
    student.table.subject[2] = 'D';
    student.table.subject[3] = 'E';
    student.table.subject[4] = 'F';
    

    (Note: For a large number of elements, that would get tedious and be an inefficient use of executable memory unless the compiler can optimize it to the equivalent of a memcpy.)