【问题标题】:将字符串存储到C中的链表
【发布时间】:2022-01-21 12:11:52
【问题描述】:

在我的问题中,我需要从 txt 文件中读取行。
每行包含 student_id、姓名、出生日期、性别、部门和年级(班级)。
例如 (155898933;Nuh Kaplan;26/01/1998;M;ME;2)
然后我需要将它们存储在链接列表中。
我声明我的结构如下:

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;
};

然后我用这部分代码读取行并存储在字符数组中:

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;
    } 
}

将行存储到字符数组后,我需要将它们存储在链表中。我尝试这样做:

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;
    }
}

但是,当我运行我的代码时,我得到了学生 id 和 classGrade 的垃圾值。 你能帮我解决这个问题吗?

我的洞码:

#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 文件:

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

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

输出:

输入文件名:test.txt
ID = 149875280
姓名 = 布尔库·阿克苏
出生日期 = 04/04/1994
性别 = F
部门 = CS
等级 = 3

ID = 180201201
姓名 = Mustafa Kursat Yavuz Tur
出生日期 = 12/06/1996
性别 = M
部门 = CS
等级 = 3

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

【问题讨论】:

  • 先尝试简化。你会阅读和 ech 吗?您可以存储更简单的数字数据类型而不是字符串吗? IE。您是否设法解决了课堂上的最后几个练习?
  • 为什么要声明 char 数组,而应该创建 Node 类型的数组。仅将字符串值类型转换为 int 不会正确转换 2 个整数字段。使用atoi()之类的转换函数
  • 一开始你不需要任何 3d char 数组,所以第一步是把它扔掉,尝试一个简单的方法:读取第一个学生记录,把它放在第一个列表中节点;读取下一个学生记录,放入下一个列表节点;重复直到完成。现在您不再需要任何数组,您可以专注于两个单独的子任务:(1)从文件中读取一个学生记录(2)基于一个学生记录创建一个列表节点。为(1)编写代码,确保它有效。 然后为(2)编写代码,确保它有效。 然后将它们组合成一个循环。订单很重要!

标签: arrays c struct linked-list


【解决方案1】:

为什么要声明 char 数组,而不是创建 Node 类型的数组。仅将字符串值类型转换为 int 不会正确转换 2 个整数字段。使用atoi() 之类的转换函数。 改变这一行,

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

p-&gt;id = atoi(arr[i][j]);

【讨论】:

  • 我将p-&gt;id = (int)arr[i][j]; 更改为p-&gt;id = atoi(arr[i][j])。程序正确打印学生证号码。但是,当我尝试对p-&gt;classGrade = (int) arr[i][j+5] 执行相同的过程时,程序会在 ID 部分和 ClasGrade 部分打印 classGrades。我该如何解决这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 2022-01-15
  • 2016-03-04
相关资源
最近更新 更多