'C,Reading From File,Prinintg, Syntax Error identifier

Im trying to run my c code. but im getting a problem and really tried that much to get the right thing and i couldnt know what the problem. what is visual studio telling me that, i have syntax error also missed "}" but i checked every thing and its still give me the error if there is an error cause of structure please tell me how to fix this but if its another help me to get the right think thank you so much. this is my code below.

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct University
{
    Student* arr;
}University;
typedef struct Student
{
    char* name;
    long id;
    float grade;
    char labor[5];
    char finalg;

}Student;
int readfile(University uni);
void outputfile(University uni, int n);
int main()
{
    int n;
    University uni;
    n=readfile(uni);
    outputfile(uni, n);

    return 0;
}
int readfile(University uni)
{
    FILE* fp;
    char name[100], ch[5];
    long id;
    float grade;
    int cnt = 0, i, j;
    fp = fopen("input.txt", "rt");
    if (fp == NULL)
    {
        printf("ERROR: Cannot open input file.\n");
        return 1;
    }
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
    {
        if (cnt == 0)
        {
            uni.arr = (Student*)malloc(1 * sizeof(Student));
            if (uni.arr == NULL)
            {
                printf("No Memory to allocation.\n");
                exit(1);
            }
            cnt++;
        }
        else if (cnt >= 1)
        {
            uni.arr = (Student*)realloc(uni.arr, (cnt + 1) * sizeof(Student));
            if (uni.arr == NULL)
            {
                printf("No Memory to allocation.\n");
                exit(1);
            }
            cnt++;
        }
        for (i = cnt - 1; i < cnt;i++)
        {
            uni.arr[i].name = (char*)malloc((strlen(name) + 1) * sizeof(char));
            if (uni.arr[i].name == NULL)
            {
                printf("No Memory to allocation.\n");
                exit(1);
            }
            uni.arr[i].id = id;
            uni.arr[i].grade = grade;
            for (j = 0;j < 5;j++)
                uni.arr[i].labor[j] = ch[j];
        }
    }
    return cnt;
}
void outputfile(University uni, int n)
{
    FILE* fo;
    int i,check,j;
    fo = fopen("outputfile.txt", "w");
    for (i = 0;i < n;i++)
    {
        check = 0;
        for (j = 0;j < 5;j++)
            if (uni.arr[i].labor[j] == 1)
                check++;
        if (check < 3)
            check = 0;
        else
            check = 1;
        fprintf(fo,"Student[%d]: %s %.2f %d", i+1,uni.arr[i].name,uni.arr[i].grade,check);
    }
}

the inputfile is :

michel 123 90.1 11001
alex 234 92.3 10011
Linda 345 89.4 10001
Shoco 456 90.6 01001

the outfile that i want is :

Student 1: michel 123 90.1 1
Student 2: alex 234 92.3 1
Student 3: Shoco 456 90.6 0
……………..
…………….
Student n: Shoco 456 90.6 0


Solution 1:[1]

Syntax errors

In the C Playground (editable) I get the following errors:

/cplayground/code.cpp:7:5: error: unknown type name 'Student'
    Student* arr;
    ^

Here, in the definition of University, you are referencing Student before it has been defined. Move the definition of Student to before University and it'll work.

The following errors all belong together, explained below:

/cplayground/code.cpp:42:29: warning: invalid conversion specifier ' ' [-Wformat-invalid-specifier]
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
                         ~~~^
/cplayground/code.cpp:42:44: warning: format specifies type 'float *' but the argument has type 'long *' [-Wformat]
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
                             ~~            ^~~
                             %ld
/cplayground/code.cpp:42:49: warning: format specifies type 'char *' but the argument has type 'float *' [-Wformat]
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
                                ~~              ^~~~~~
                                %f

These all relate to the use of %l which is not a complete specifier. The first error tells you this, the other two are because the following specifiers and arguments are out of sync. Fix the first error, the rest will go away.

Finally:

/cplayground/code.cpp:42:57: warning: data argument not used by format string [-Wformat-extra-args]
    while (fscanf(fp, "%s %l %f %c", name, &id, &grade, &ch) > 0)
                      ~~~~~~~~~~~~~                     ^
4 warnings and 1 error generated.

Here you have used %c to indicate a single char, but are passing a char ** (address of the ch array). I suspect you want %s for a C string, and then you'll want to pick just the first element if that's what your intended output wants (NB: C Playground lets you upload a ZIP containing test input files, look under the cog option if you want to try it there).

Argument passing by value

In the definition and implementation of readfile and outputfile you are passing by value. This means that the function is updating a copy of the uni variable and not the one passed. So anything added by readfile won't reach outputfile.

int readfile(University uni);
void outputfile(University uni, int n);

You need to change the declaration and implementation to pass a pointer, thus:

int readfile(University *uni);
void outputfile(University *uni, int n);

Then, within both functions, change the . accessor to -> to dereference the pointer. e.g.

uni->arr = (Student*)malloc(1 * sizeof(Student));
if (uni->arr == NULL)

Logic errors

There are other logic errors that prevent it from running correctly, but I'll leave that for the OP.

Notably, the for loop after allocating the new student is unnecessary (it'll only ever loop once, its meant to be targetting the 'empty' element at the end of the array).

A good thing to do here would be to get a pointer to the last element, then use that to simplify the logic.

Student *student = uni->arr[cnt-1];
strcpy(student->name, name);
//...

You also forgot to copy over the name.

If there is no input file, you should exit() rather than return, or you'll get a segmentation fault.

There's more besides by the looks of things, but hopefully this takes you further, and you can come back then.

Here is an updated playground that get's as far as the logic errors.

Solution 2:[2]

I think there is a pointers issue with structure building in university struct You need to rewrite the pointers.

Solution 3:[3]

I suggest you to go look into your compilers error, there's plenty of them! For example:

main.c:66:23: error: request for member ‘name’ in something not a structure or union
   66 |             uni.arr[i].name = (char*)malloc((strlen(name) + 1) * sizeof(char));
      |                       ^
main.c:67:27: error: request for member ‘name’ in something not a structure or union
   67 |             if (uni.arr[i].name == NULL)
      |                           ^
main.c:72:23: error: request for member ‘id’ in something not a structure or union
   72 |             uni.arr[i].id = id;
      |                       ^
main.c:73:23: error: request for member ‘grade’ in something not a structure or union
   73 |             uni.arr[i].grade = grade;
      |                       ^
main.c:75:27: error: request for member ‘labor’ in something not a structure or union
   75 |                 uni.arr[i].labor[j] = ch[j];

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dave Meehan
Solution 2 Mreos
Solution 3 al366io