gpt4 book ai didi

c - 从C中的txt文件中读取链表

转载 作者:行者123 更新时间:2023-11-30 14:55:58 25 4
gpt4 key购买 nike

我正在尝试从文件中读取链接列表,但没有成功。结构已使用 fprintf 正确保存(无法使其与 fwrite 一起使用)。这是我的结构:

typedef struct database
{
int id;
int nrindeksu;
char *imie;
char *nazwisko;
char *wydzial;
char *kierunek;
struct database* link;
} data;

char buffer[1024]; //changed buffer size

我使用此功能将链接列表保存到文件:编辑:对其他功能进行一些更改后,此功能崩溃。

void save(data* head)
{
FILE *fp;
fp = fopen("test.txt", "w");
data* current = head->link;

while (current != NULL) {
fprintf(fp,"%d ",current->nrindeksu);
fprintf(fp,"%s ",current->imie);
fprintf(fp,"%s ",current->nazwisko);
fprintf(fp,"%s ",current->wydzial);
fprintf(fp,"%s\n",current->kierunek);
current = current->link;
}
fclose(fp);
}

并尝试使用以下命令从文件中读取它:

void read(data* head)
{
data* current = head;
FILE *fp;
fp = fopen("test.txt", "r");

while(//I still need help with this loop)
fscanf(fp, "%d", current->link->nrindeksu);

fscanf(fp, "%s", buffer);
current->link->imie=malloc(strlen(buffer) + 1);
if(current->link->imie == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->imie, buffer);

fscanf(fp, "%s", buffer);
current->link->nazwisko=malloc(strlen(buffer) + 1);
if(current->link->nazwisko == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->nazwisko, buffer);

fscanf(fp, "%s", buffer);
current->link->wydzial=malloc(strlen(buffer) + 1);
if(current->link->wydzial == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->wydzial, buffer);

fscanf(fp, "%s", buffer);
current->link->kierunek=malloc(strlen(buffer) + 1);
if(current->link->kierunek == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->kierunek, buffer);

fclose(fp);
}

知道为什么它不读取任何内容吗?另外,我不知道如何编写一个循环来确定应该停止从文件读取的位置。

编辑:我正在使用此函数将项目添加到列表中:

void add_bottom(data* head) 
{
data* current = head;

while (current->link != NULL)
{
current = current->link;
}

current->link = malloc(sizeof(*current));//changed every malloc
if(current->link == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}

printf("Podaj nr indeksu studenta: ");
scanf("%d", current->link->nrindeksu);

printf("Podaj imie studenta: ");
fflush(stdin);
scanf("%19[^\n]", buffer);
current->link->imie=malloc(strlen(buffer) + 1);
if(current->link->imie == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->imie, buffer);

printf("Podaj nazwisko studenta: ");
fflush(stdin);
scanf("%19[^\n]", buffer);
current->link->nazwisko=malloc(strlen(buffer) + 1);
if(current->link->nazwisko == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->nazwisko, buffer);

printf("Podaj wydzial studenta: ");
fflush(stdin);
scanf("%29[^\n]", buffer);
current->link->wydzial=malloc(strlen(buffer) + 1);
if(current->link->wydzial == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->wydzial, buffer);

printf("Podaj kierunek studenta: ");
fflush(stdin);
scanf("%29[^\n]", buffer);
current->link->kierunek=malloc(strlen(buffer) + 1);
if(current->link->kierunek == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->kierunek, buffer);

current->link->link = NULL;
}

主要:

int main(int argc, char *argv[]) 
{
char c;
head = init(head);
if(head == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
read(head);
do{
printf("Baza danych - wybierz opcje: [d]odaj, [w]yswietl, [u]sun, [k]oniec: ");
scanf("%c", &c);
if(c=='d')
{
system("cls");
add_bottom(head);
}
if(c=='w')
{
system("cls");
show(head);
}
if(c=='u')
{
system("cls");
show(head);
remove_by_id(&head);
system("cls");
show(head);
printf("\n");
}
fflush(stdin);

}while(c!='k');
save(head);
free(head);
return 0;
}

另外函数 init 只是

head = calloc(1,sizeof(data));

这样第一个节点始终为 NULL,无法让它以其他方式创建或编辑第一个节点。

最佳答案

评论网站您的代码有几个问题。有关其中一些的说明...

声明(其中 6 条):

fscanf("%d", &nrindeksu);

...原样不允许您发布的代码进行编译,因为 fscanf() 要求将 FILE * 用作第一个参数。

fscanf(fp, "%d", &nrindeksu);

函数strlen(nazwisko)(与您帖子中的所有其他类似行一样)仅返回缓冲区的长度而不考虑 NULL 终止符,这将需要接收缓冲区的长度,current->link->nazwisko

至少,您可以通过显式为 NULL 终止符添加空格来解决此问题:

current->link->nazwisko=(char*)malloc(sizeof(char) * strlen(nazwisko) + 1);
^^^^^^^ ^^^^^^^^^^^^^^ ^^^
not necessary necessary

因为sizeof(char)总是== 1,所以没有必要

清理完毕:

current->link->nazwisko=malloc(strlen(nazwisko) + 1);

或者,按照评论中的建议(如果 POSIX 是一个选项),您可以使用 strdup()

char *tmp = 0;
tmp = strdup(nazwisko);
if(tmp)
{
current->link->nazwisko = tmp;
strcpy(current->link->nazwisko, nazwisko);
}

还有一个小问题。以下是合法的,并且确实分配了足够的空间:

current->link = malloc(sizeof(data));

但是这种形式:

current->link = malloc(sizeof(*current));

generally recommended ,因为在 sizeof 表达式中最好使用变量,而不是类型

还有一条评论, it is not necessary to cast the return of [m][c]alloc when using C

编辑(编辑代码以使其能够编译和运行。[完成内存泄漏])

//does not include global declarations of struct data and variables
void read(data** head); //so object can be changed when passes as function argument
// ^
void save(data* head);


int main(void)
{
data *h = calloc(1, sizeof(data));
read(&h); //note, passing to data **, not data *
save(h);

return 0;
}

void save(data* head)
{
FILE *fp;
fp = fopen("text2.txt", "w");
//data* current = head->link;

fprintf(fp,"%d ",head->link->nrindeksu);
fprintf(fp,"%s ",head->link->imie);
fprintf(fp,"%s ",head->link->nazwisko);
fprintf(fp,"%s ",head->link->wydzial);
fprintf(fp,"%s\n",head->link->kierunek);
fclose(fp);
}


void read(data **head)
{
data *current = calloc(1, sizeof(*current));
current = *head;
int count;
FILE *fp;
fp = fopen(".\\text.txt", "r");

{
current->link = malloc(sizeof(data));
if(current->link == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
count = fscanf(fp,"%d %s %s %s %s", &nrindeksu, imie, nazwisko, wydzial, kierunek);
if(count != 5)
{
free(current);
return
}
current->link->nrindeksu = nrindeksu;

current->link->imie=(char*)malloc(sizeof(char) * strlen(imie)+1);
if(current->link->imie == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->imie, imie);

current->link->nazwisko=(char*)malloc(sizeof(char) * strlen(nazwisko)+1);
if(current->link->nazwisko == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->nazwisko, nazwisko);

current->link->wydzial=(char*)malloc(sizeof(char) * strlen(wydzial)+1);
if(current->link->wydzial == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->wydzial, wydzial);

current->link->kierunek=(char*)malloc(sizeof(char) * strlen(kierunek)+1);
if(current->link->kierunek == NULL) {
fprintf(stderr, "Malloc error");
exit(0);
}
strcpy(current->link->kierunek, kierunek);

current->link->link = NULL;
}
fclose(fp);
}

注意:上面的代码确实将数据读入节点,并且能够将节点数据写入文件,但您必须进行内存清理。没有任何东西被释放。我在上面的评论中发布的链接将有助于解决这个问题。

编辑 2(基于 this tutorial link 中的函数)

以下代码会将文本文件(请参阅代码底部的示例文件)读取到链接列表中,然后将列表的内容写入第二个文本文件中,然后清理所有使用的内存。

typedef struct database
{
int id;
int nrindeksu;
char *imie;
char *nazwisko;
char *wydzial;
char *kierunek;
struct database* link;
}data;

typedef struct {
int id;
int nrindeksu;
char imie[20];
char nazwisko[20];
char wydzial[30];
char kierunek[30];
}LINE;

LINE line;

void push(data** head_ref, LINE *line);
void store(data *d, FILE *p);
void cleanup(data *d);

int main(void)
{
data *head = NULL;
FILE *fp;
fp = fopen(".\\text1.txt", "r");
if(fp)
{
while(fscanf(fp,"%d %s %s %s %s", &line.nrindeksu, line.imie, line.nazwisko, line.wydzial, line.kierunek)== 5)
{
push(&head, &line);
}
fclose(fp);
}
fp = fopen(".\\text2.txt", "w");
if(fp)
{
store(head, fp);
fclose(fp);
}
cleanup(head);
return 0;
}

/// synonymous with your "read()"
void push(data** head_ref, LINE *line)
{
/* 1. allocate node */
data *new_node = malloc(sizeof(*new_node));

/* 2. put in the data */
new_node->id = line->id;
new_node->nrindeksu = line->nrindeksu;
new_node->imie = calloc(1, strlen(line->imie)+1);
strcpy(new_node->imie, line->imie);
new_node->nazwisko = calloc(1, strlen(line->nazwisko)+1);
strcpy(new_node->nazwisko, line->nazwisko);
new_node->wydzial = calloc(1, strlen(line->wydzial)+1);
strcpy(new_node->wydzial, line->wydzial);
new_node->kierunek = calloc(1, strlen(line->kierunek)+1);
strcpy(new_node->kierunek, line->kierunek);

/* 3. Make next of new node as head */
new_node->link = (*head_ref);

/* 4. move the head to point to the new node */
(*head_ref) = new_node;
}


void store(data *d, FILE *p)
{
char line[260];
while(d != NULL)
{
sprintf(line, "%d %s %s %s %s\n", d->nrindeksu, d->imie, d->nazwisko, d->wydzial, d->kierunek);
fputs(line, p);
d = d->link;
}
}

void cleanup(data *d)
{
data *tmp;

while(d != NULL)
{
tmp = d;

if(tmp->imie) free(d->imie);
if(tmp->nazwisko) free(d->nazwisko);
if(tmp->wydzial) free(d->wydzial);
if(tmp->kierunek) free(d->kierunek);
d = d->link;
free(tmp);
}
free(d);
}

作为代码示例输入引用的文本文件:

text1.txt:

0 string01 string02 string03 string04
1 string11 string12 string13 string14
2 string21 string22 string23 string24
3 string31 string32 string33 strin3g4
4 string41 string42 string43 string44
5 string51 string52 string53 string54
6 string61 string62 string63 string64
7 string71 string72 string73 string74
8 string81 string82 string83 string84
9 string91 string92 string93 string94

关于c - 从C中的txt文件中读取链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45107563/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com