【发布时间】: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