Home > Software engineering >  unable to read data from textfile and put it to structs and union to get output in another textfile
unable to read data from textfile and put it to structs and union to get output in another textfile

Time:07-11

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;
    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);
        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");
    }
    // close file
    fclose (infile);
    fclose(ofp);
 
    return 0;
}

I appreciate any help!

CodePudding user response:

The answer

You're never initialising the values of data[1] to data[5]. In C variables with automatic storage duration aren't initialised and have an undefined value. You need to initialise them :

data[1] = (PERSON){.type = 's', .u.stu = (STUDENT){0}};
data[2] = (PERSON){.type = 's', .u.stu = (STUDENT){0}};
data[3] = (PERSON){.type = 's', .u.stu = (STUDENT){0}};
data[4] = (PERSON){.type = 's', .u.stu = (STUDENT){0}};
data[5] = (PERSON){.type = 's', .u.stu = (STUDENT){0}};

More details

In C there are multiple type of storage class : static, auto, register and extern. The most important to know are the static and automatic storage class specifiers. A static variable exists during the whole program execution and an automatic variable exists only while its context is being executed (when the program is inside a function for example).

By default, variables declared outside of a function body are static, and variable inside a function body are automatic. You can force a local variable to be stored statically by using the static keyword.

Most importantly, automatic variables aren't initialised when declared but they still point to a chunk of memory. This means that reading from a variable that hasn't been initialised will simply return garbage. That's probably what you are getting.

CodePudding user response:

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, " [^/]" "/" "%d " "/" 
      "%d " "/" "%d " "/" 
      " %9[^/]" "/" " %4[^/]" "/" 
      " I[^/]" "/" " %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
    }
  }
  • Related