Search code examples
cfilestructiounions

unable to read data from textfile and put it to structs and union to get output in another textfile and output window


I just started learning the C language and have problems with structures and input/output stream understanding. I am trying to make a code that will read existing information in the created text file, input it into structures that are united by the union, and copy it to newly created through the code text file. I also try to make this information appear in the output window. Below is an example of code I tried to make, but it gives me a strange output and I'm not sure what I suppose to do here.From the text file I'm trying to read the info of student ID, name, school status, how many times awarded with scholarship, phone, age, cgpa, if studying abroad now or not. My file looks like this:

name/ ID/ age/ scholarship/ schoolstat/ abroad/ address/ phone/ cgpa

mark/ 20091111/ 20/ 1/ Yes/ No/ city,district,street,house/ 1234567890/ 3.0

#include <stdio.h>
#include <stdlib.h>
#include<string.h>


typedef struct{

    char name[20];
    char mail[30];
    int mobile;
    }PROFESSOR;

typedef struct{

    char name[20];
    char address[50];
    char schoolstat[10];
    int scholarship[5];
    char abroad[10];
    int phone;
    int age;    
    int ID;
    float cgpa;
    }STUDENT;

typedef struct{

    char type;
    union {
        PROFESSOR prof;
        STUDENT stu;
    }u;
    }PERSON;
 
// Driver program

int main () {

    FILE *infile, *ofp;
    PERSON data[6];
    int i;
    char name[20];
    char address[50];
    char schoolstat[10];
    int scholarship[5];
    char abroad[10];
    int phone;
    int age;    
    int ID;
    float cgpa;
    
    infile = fopen ("inputfile.txt", "r");
    if (infile == NULL)
    {
        fprintf(stderr, "\nError opening file\n");
        exit (1);
    }
    ofp=fopen("outputfile.txt", "w");
    if(ofp==NULL){
        printf("output file open error!\n");
        return 1;
    }
    data[0].type = 'p';
    strcpy(data[0].u.prof.name, "Sam");
    strcpy(data[0].u.prof.mail, "[email protected]");
    data[0].u.prof.mobile = 1234567;
    
    data[1].type = 's';
    data[2].type = 's';
    data[3].type = 's';
    data[4].type = 's';
    data[5].type = 's';
    
    int total = 0;
    int total_age=0;
    int newline=0;
    
    int res;
    char c;
    int i;
    while(1){
        res=fscanf(infile, "%d %d %d %d %s %s %s %d %f\n", name, &ID, &age, &scholarship, &schoolstat, &abroad, &address, &phone, &cgpa);
        if(res==EOF) break;
        fprintf(ofp, "%d %s %d %d %s %s %s %d %f\n", ID, name, age, scholarship, schoolstat, abroad, address, phone, cgpa);
        i++;
        if(i==5) break;
        total = total + cgpa;
        total_age = total_age + age;
        for(newline=0; newline<res; newline++){
            if(name[c]=='\0'){
                newline++;
            }
        }   
    }
    for(i=0; i<6; i++){
        switch(data[i].type){
            case 'p':
                printf("professor %s\n", data[i].u.prof.name);
                printf("%s, %d\n", data[i].u.prof.mail, data[i].u.prof.mobile);
                break;
            case 's':
                printf("student %s %d %d %d %s %s %s %d %f\n", data[i].u.stu.name, data[i].u.stu.age, data[i].u.stu.ID, data[i].u.stu.scholarship, data[i].u.stu.schoolstat, data[i].u.stu.abroad,
                 data[i].u.stu.address, data[i].u.stu.phone, data[i].u.stu.cgpa);
                break;
                }
                printf("\n");
    }
    printf("Number of lines: %d", newline);
    // close file
    fclose (infile);
    fclose(ofp);
 
    return 0;
}

I appreciate any help!

now output is like the next: professor Sam [email protected], 1234567

student 0 0 6486936 0 0.000000

student 0 0 6487068 0 0.000000

student 0 0 6487200 0 0.000000

student 0 0 6487332 0 0.000000

Number of lines: 0


Solution

  • Format uses '/' as a separator. Use "%width[^/]" to read a string token.

    Use " %n" to record offset of scan, if it made it that far.


    After a successful fopen() read a line

    #define LINE_MAX 135    // Longest expected line
    char line[LINE_MAX*2];  // Be generous and read even more
    if (fgets(line, sizeof line, ofp)) {
    

    Now parse it

      STUDENT st = { 0 };
      int n = 0;
      // Format broken up to help illustrate parsing
      sscanf(line, " %19[^/]" "/" "%d " "/" 
          "%d " "/" "%d " "/" 
          " %9[^/]" "/" " %4[^/]" "/" 
          " %49[^/]" "/" " %d " "/" 
          "%f " " %n",
          st.name, &st.ID,
          &st.age, &scholarship[0], 
          st.schoolstat, st.abroad,
          st.address, &st.phone,
          st.cgpa, &n);  
        // Check if scan completed with no extra trailing junk
        if (n == 0 || line[n] != '\0') {
          ; // Handle bad input
        } else {
          ;  Use input
        }
      }