0

In my problem, I need to read lines from a txt file.
Each line contains student_id, name, birthdate, gender, department, and grade(class).
e.g ( 155898933;Nuh Kaplan;26/01/1998;M;ME;2 )
Then I need to store them in a Linked List.
I declared my structure as follows:

struct Node{
    int id;
    char name[100];
    int date; //YYYYMMDD (String date will be converted to integer. I created dateStrInt function for this conversion.)
    char gender[2];
    char departmentCode[6];
    int classGrade;
    struct Node *next;
};

Then I read lines and store in an character array with this part of code:

if (fptr != NULL) {
    while (fgets (buff, 100, fptr)) {
        char* split = strtok(buff, ";");
        while( split != NULL ) {
            strcpy(arr[i][j], split); 
            j++;
            split = strtok(NULL, ";");
        }
        i++;
        j = 0;
    } 
}

After I stored lines into character array, I need to store them in a linked list. I tried to do it as follows:

for(int i = 0; i < len; i++) {
    p = (struct Node*) malloc(sizeof(struct Node));
    j = 0;
    p->id = (int)arr[i][j];
    strcpy(p->name, arr[i][j+1]);
    p->date = dateStrInt(arr[i][j+2]);
    strcpy(p->gender,arr[i][j+3]);
    strcpy(p->departmentCode, arr[i][j+4]);
    p->classGrade = (int)arr[i][j+5];
      
    j = 0;

    if(list == NULL){
        list = p;
        p -> next = NULL;
        last = p;
    }
    else {
        last -> next = p;
        p -> next = NULL;
        last = p;
    }
}

However when I run my code, I get garbage values for student id and classGrade. Can you help me to solve this problem?

My hole code:

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

struct Node {
    int id;
    char name[100];
    int date; //YYYYMMDD
    char gender[2];
    char departmentCode[6];
    int classGrade;
    struct Node *next;
};

int dateStrInt(char str[]) {
    int d, m, y;
    sscanf(str, "%d/%d/%d", &d, &m, &y);
    return (y * 10000 + m * 100 + d);
} 

int countLines(char* filename) {
    int count = 0;
    FILE *fptr;
    fptr = fopen(filename, "r");
    if(fptr == NULL){
        printf("File does not exist.");
        exit(1);
    }
    else {
        for(char ch = getc(fptr); ch != EOF; ch = getc(fptr)) {
            if(ch == '\n'){
                count++;
            }
        }
    }
    return count + 1;
 }

 struct Node* createList(struct Node* list, int len, char filename[]){
     struct Node* last;
     struct Node* p;
     char buff[100];
     char arr[len][6][100];
     int i = 0, j = 0;
     FILE* fptr = fopen(filename,"r");


     if (fptr != NULL) {
         while (fgets (buff, 100, fptr)) {
             char* split = strtok(buff, ";");
             while( split != NULL ) {
                 strcpy(arr[i][j], split); 
                 j++;
                 split = strtok(NULL, ";");
             }
             i++;
             j = 0;
         } 
     }



     int o = 0;
     for(int k = 0; k < len; k++){
         printf("\nID = %s", arr[k][o]);
         printf("\nName = %s", arr[k][o+1]);
         printf("\nBirth Date = %s", arr[k][o+2]);
         printf("\nGender = %s", arr[k][o+3]);
         printf("\nDepartment = %s", arr[k][o+4]);
         printf("\nGrade = %s", arr[k][o+5]);
         o = 0;
     }


 
     for(int i = 0; i < len; i++){
         p = (struct Node*) malloc(sizeof(struct Node));
         j = 0;
         p->id = (int)arr[i][j];
         strcpy(p->name, arr[i][j+1]);
         p->date = dateStrInt(arr[i][j+2]);
         strcpy(p->gender,arr[i][j+3]);
         strcpy(p->departmentCode, arr[i][j+4]);
         p->classGrade = (int)arr[i][j+5];
      
         j = 0;

         if(list == NULL){
             list = p;
             p -> next = NULL;
             last = p;
         }
         else {
             last -> next = p;
             p -> next = NULL;
             last = p;
         }
    }  
    return list;
}

void printList(struct Node *list, int len){
    struct Node *p;
    p = list;
    int cnt = 0;
    printf("\nThe list = ");
    while(p != NULL) {
       if(cnt != len - 1) {
           printf("\n{%d, %s, %d, %s, %s, %d} ---->",p->id, p->name, p->date,
           p->gender, p->departmentCode, p->classGrade);
           cnt++;
       }
       else
           printf("\n{%d, %s, %d, %s, %s, %d} ",p->id, p->name, p->date,
           p->gender, p->departmentCode, p->classGrade);
           p = p->next;
       }
 }

 int main(void) {

     struct Node *head = NULL;
     char filename[10];
     printf("Enter file name: ");
     scanf("%s", filename);
     int len = countLines(filename);

     struct Node* list = createList(head, len, filename);
     printList(list, len);
 }

test.txt file :

149875280;Burcu Aksu;04/04/1994;F;CS;3

180201201;Mustafa Kursat Yavuz Tur;12/06/1996;M;CS;3

Output:

Enter file name: test.txt
ID = 149875280
Name = Burcu Aksu
Birth Date = 04/04/1994
Gender = F
Department = CS
Grade = 3

ID = 180201201
Name = Mustafa Kursat Yavuz Tur
Birth Date = 12/06/1996
Gender = M
Department = CS
Grade = 3

The list =
{-1883589280, Burcu Aksu, 19940404, F, CS, -1883588780} ---->
{-1883588680, Mustafa Kursat Yavuz Tur, 19960612, M, CS, -1883588180}

4
  • Try to simplify first. Can you read and ech? Can you store the simpler data type of numbers instead of strings? I.e. did you manage to sovle the last few exercises in your class? Commented Dec 19, 2021 at 15:56
  • Please provide a minimal reproducible example. Commented Dec 19, 2021 at 15:57
  • Why are you declaring char array, instead you should be creating array of Node type. Just typecasting string value to int will not convert the 2 integer fields correctly. Use the conversion function like atoi() Commented Dec 19, 2021 at 17:25
  • 1
    You don't need any 3d char array in the first place, so the first step would be to throw it out and try a straightforward approach: read the first student record, put it in the first list node; read the next student record, put it in the next list node; repeat until done. Now that you don't need any array any more, you can concentrate on the two separate subtasks: (1) read one student record from a file (2) create one list node based on one student record. Write code for (1), make sure it works. Then write code for (2), make sure it works. Then combine them in a loop. Order matters! Commented Dec 19, 2021 at 17:28

1 Answer 1

1

Why are you declaring char array, instead you should be creating array of Node type. Just typecasting the string value to int will not convert the 2 integer fields correctly. Use the conversion function like atoi(). Change this line,

p->id = (int)arr[i][j];

to p->id = atoi(arr[i][j]);

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.