将文件加载到C中的链表中,有时有效,有时无效
Loading file into linked list on C, sometimes works, sometimes doesnt
这是我用来加载它的函数,有时它可以运行,但是当我离开程序并再次编译时,它就会崩溃:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//this is how I declared the list
struct plantillas {
int iduser;
int idplant;
char name[31];
int pres;
int punt;
struct plantillas *next;
};
struct plantillas *first, *last;
//This is the main that calls loadfile:
int main(){
FILE *file;
file = fopen("Plantillas.txt", "r");
puts("a");
load_file(file);
fclose(file);
}
//this is the funcion that actually loads the file
void load_file(FILE *file) {
char cadaux[100];
first = (struct plantillas *) NULL;
last = (struct plantillas *) NULL;
struct plantillas *new;
while (!feof(fichero)){
/* save memory for the new element on the list */
new = (struct plantillas *) malloc(sizeof(struct plantillas));
if (new == NULL) printf("No memory avaiable!\n");
fflush(stdout);
readline(file, cadaux); //I'll explain about this later
sscanf(cadaux, "%d %d %s %d %d", &new->iduser, &new->idplant, new->name, &new->pres, &new->punt);
new->next = NULL;
/* this will find out if the linked list is empty or not */
if (first == NULL) {
first = new;
last = new;
}
else {
/* if it isn't, the one that was last before now has to point to the next element on the list */
last->next = new;
/* now we make the new be the last */
last = new;
}
}
}
/*The readline function is because of format issues. As it is an assignment for school, the format of the file has to be in1-int2- string1-int3-int4, readline reads each line on the file and turn the '-' into ' ' and then saves it into an auxiliary string. Here is the function:*/
void readline(FILE * a, char * b)
{
int i;
fscanf(a, "%s", b);
for (i = 0; b[i] != '\n'; i++)
{
if (b[i] == '-') b[i] = ' ';
}
}
抱歉,如果有一些变量根本不匹配,我将代码从西班牙语翻译过来,试图让它更容易理解。另外,对于格式问题,我很抱歉,这是我的第一个 post,我遇到了一些麻烦
您的代码中有两个 主要 错误会导致问题。
首先是你不应该做while (!feof(...))
,因为EOF
标志直到你尝试从文件之外读取才被设置,导致循环迭代一次到多次。这很糟糕但不是致命的,因为它所做的只是导致您最后添加一个带有虚拟数据的额外节点。
第二个也是绝对致命的错误是您使用 fscanf
读取一个不包含换行符(或根本不包含任何白色-space)的字符串,然后您寻找写入缓冲区时换行。因为您读取的字符串不包含换行符,所以 fscanf
之后的循环将超出缓冲区的末尾,您很可能会在堆栈的某处写入数据,从而导致 未定义的行为。该循环的正确条件是查找字符串终止符 '[=14=]'
.
解决这两个问题我的建议是不要有readline
函数,而是使用fgets
,并使用while (fgets(cadaux, sizeof(cadaux), file) != NULL)
作为循环条件,以及一个函数来用 spaces 替换 '-'
字符,并在该函数中检查 both 换行符和循环中的字符串终止符。
这是我用来加载它的函数,有时它可以运行,但是当我离开程序并再次编译时,它就会崩溃:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//this is how I declared the list
struct plantillas {
int iduser;
int idplant;
char name[31];
int pres;
int punt;
struct plantillas *next;
};
struct plantillas *first, *last;
//This is the main that calls loadfile:
int main(){
FILE *file;
file = fopen("Plantillas.txt", "r");
puts("a");
load_file(file);
fclose(file);
}
//this is the funcion that actually loads the file
void load_file(FILE *file) {
char cadaux[100];
first = (struct plantillas *) NULL;
last = (struct plantillas *) NULL;
struct plantillas *new;
while (!feof(fichero)){
/* save memory for the new element on the list */
new = (struct plantillas *) malloc(sizeof(struct plantillas));
if (new == NULL) printf("No memory avaiable!\n");
fflush(stdout);
readline(file, cadaux); //I'll explain about this later
sscanf(cadaux, "%d %d %s %d %d", &new->iduser, &new->idplant, new->name, &new->pres, &new->punt);
new->next = NULL;
/* this will find out if the linked list is empty or not */
if (first == NULL) {
first = new;
last = new;
}
else {
/* if it isn't, the one that was last before now has to point to the next element on the list */
last->next = new;
/* now we make the new be the last */
last = new;
}
}
}
/*The readline function is because of format issues. As it is an assignment for school, the format of the file has to be in1-int2- string1-int3-int4, readline reads each line on the file and turn the '-' into ' ' and then saves it into an auxiliary string. Here is the function:*/
void readline(FILE * a, char * b)
{
int i;
fscanf(a, "%s", b);
for (i = 0; b[i] != '\n'; i++)
{
if (b[i] == '-') b[i] = ' ';
}
}
抱歉,如果有一些变量根本不匹配,我将代码从西班牙语翻译过来,试图让它更容易理解。另外,对于格式问题,我很抱歉,这是我的第一个 post,我遇到了一些麻烦
您的代码中有两个 主要 错误会导致问题。
首先是你不应该做while (!feof(...))
,因为EOF
标志直到你尝试从文件之外读取才被设置,导致循环迭代一次到多次。这很糟糕但不是致命的,因为它所做的只是导致您最后添加一个带有虚拟数据的额外节点。
第二个也是绝对致命的错误是您使用 fscanf
读取一个不包含换行符(或根本不包含任何白色-space)的字符串,然后您寻找写入缓冲区时换行。因为您读取的字符串不包含换行符,所以 fscanf
之后的循环将超出缓冲区的末尾,您很可能会在堆栈的某处写入数据,从而导致 未定义的行为。该循环的正确条件是查找字符串终止符 '[=14=]'
.
解决这两个问题我的建议是不要有readline
函数,而是使用fgets
,并使用while (fgets(cadaux, sizeof(cadaux), file) != NULL)
作为循环条件,以及一个函数来用 spaces 替换 '-'
字符,并在该函数中检查 both 换行符和循环中的字符串终止符。