从C上的文本文件创建双向链表

我必须从文本文件中创建一个双向链表,其中每一行都有时间和温度。 例如,每一行都是这样的:12:48 23.69

因此,我无法将数据放入双向链表中。 我不知道如何实现它。 所以我做了一个元素的typedef结构数组,并希望我可以从数组的第一个元素开始,然后指向数组的第二个元素的下一个元素。 这就是我的……

所以这是双链表的头文件:

#include typedef struct tempdata_{ int *hour; int *min; int *temp; struct tempdata_ *next; struct tempdata_ *prev; }tempdata; teypdef struct templist_{ tempdata *head; tempdata *tail; int size; }templist; 

`

这是我的主要文件:

  #include  #include "linkedlist.h" int main ( int argc, char *argv[] ) { FILE *ifp, *ofp; //char outputFilename[] = argv[2]; int SIZE = 1; tempdata tempdata1[100]; tempdata *temp, *current = NULL; if ( argc != 2 ) /* argc should be 3 for correct execution */ { /* We print argv[0] assuming it is the program name */ printf( "usage: %s filename", argv[0] ); } else { // We assume argv[1] is a filename to open ifp = fopen( argv[1], "r" ); /* fopen returns 0, the NULL pointer, on failure */ if ( ifp == 0 ) { printf( "Could not open file\n" ); } else { //ofp = fopen(outputFilename, "w"); /* reads the hours, min, tempeture integers and temperature decimals and prints them out on the screen and on the output file that is given. we dont need this printing function but I just left to have the function do something*/ while (fscanf(ifp, "%d:%d %d.%d ", &tempdata1[SIZE].hour, &tempdata1[SIZE].min, &tempdata1[SIZE].tempI, &tempdata1[SIZE].tempD) != EOF) { printf("the tempeture is %d.%d at %d:%d\n", tempdata1[SIZE].tempI, tempdata1[SIZE].tempD, tempdata1[SIZE].hour, tempdata1[SIZE].min); /*fprintf(ofp, "the tempeture is %d.%d at %d:%d\n", tempdata1[SIZE].tempI, tempdata1[SIZE].tempD, tempdata1[SIZE].hour, tempdata1[SIZE].min);*/ SIZE++; } fclose(ifp); //fclose(ofp); } } getchar(); } 

你想在你的数据结构中使用int而不是int * ,温度应该是floatdouble而不是int (这极大地简化了输入;否则,当你使用两个整数输入时正确处理26.09和26.9是相当困难的气温)。

 typedef struct tempdata tempdata; struct tempdata { int hour; int min; float temp; tempdata *next; tempdata *prev; }; 

如果没有拼写错误,你的标题会更有说服力:

 typedef struct templist templist; struct templist { tempdata *head; tempdata *tail; int size; } templist; 

拥有一组tempdata结构实际上比双重链表更明智,但我担心它会破坏练习的目标。 您可能应该根据需要动态分配结构。 我使用fgets()sscanf() ,但是你正在检查来自fscanf()的结果 – 这很好 – 但如果数据格式不正确,你可能会卡住,因为文件不在EOF但不包含fscanf()需要一个数字。 你应该检查返回值是3(每个转换字段一个),如果没有,打破循环。

要创建一个列表,你需要一个templist类型的变量,适当地初始化。

我从你的大纲中汇编了下面的程序。 给定数据文件:

 12:29 26.34 13:32 28.23 14:20 28.56 15:30 29.10 16:18 30.45 17:20 28.12 18:20 26.98 19:35 24.12 

我得到的输出是:

 Data: 12:29 26.34 Data: 13:32 28.23 Data: 14:20 28.56 Data: 15:30 29.10 Data: 16:18 30.45 Data: 17:20 28.12 Data: 18:20 26.98 Data: 19:35 24.12 Data entry complete: Head: 0x102800BB0, Tail: 0x102800C90, Size: 8 Temp: 0x102800BB0: 12:29 26.34 Temp: 0x102800BD0: 13:32 28.23 Temp: 0x102800BF0: 14:20 28.56 Temp: 0x102800C10: 15:30 29.10 Temp: 0x102800C30: 16:18 30.45 Temp: 0x102800C50: 17:20 28.12 Temp: 0x102800C70: 18:20 26.98 Temp: 0x102800C90: 19:35 24.12 

 #include  #include  #include  #include  #include  #include  typedef struct tempdata tempdata; struct tempdata { int hour; int min; float temp; tempdata *next; tempdata *prev; }; typedef struct templist templist; struct templist { tempdata *head; tempdata *tail; int size; }; static void add_to_list(templist *list, tempdata *new_temp) { assert(list != 0); assert(list->size >= 0); assert((list->head == 0 && list->tail == 0 && list->size == 0) || (list->head != 0 && list->tail != 0 && list->size != 0)); new_temp->prev = list->tail; new_temp->next = 0; list->size++; if (list->head == 0) list->head = new_temp; /* New list */ else list->tail->next = new_temp; /* Add to tail of list */ list->tail = new_temp; } static void print_temp(const tempdata *data) { printf("%d:%d %6.2f\n", data->hour, data->min, data->temp); } static void print_list(const templist *list) { const tempdata *data; assert(list != 0); assert(list->size >= 0); assert((list->head == 0 && list->tail == 0 && list->size == 0) || (list->head != 0 && list->tail != 0 && list->size != 0)); printf("Head: 0x%" PRIXPTR ", Tail: 0x%" PRIXPTR ", Size: %d\n", (uintptr_t)list->head, (uintptr_t)list->tail, list->size); for (data = list->head; data != 0; data = data->next) { printf("Temp: 0x%" PRIXPTR ": ", (uintptr_t)data); print_temp(data); } } int main(int argc, char **argv) { FILE *ifp; templist list = { NULL, NULL, 0 }; char line[2048]; if (argc != 2) { fprintf(stderr, "Usage: %s filename\n", argv[0]); return(EXIT_FAILURE); } ifp = fopen(argv[1], "r"); if (ifp == 0) { fprintf(stderr, "%s: could not open file %s (%d: %s)\n", argv[0], argv[1], errno, strerror(errno)); return(EXIT_FAILURE); } while (fgets(line, sizeof(line), ifp) != 0) { tempdata temp_val; tempdata *new_temp; if (sscanf(line, "%d:%d %f", &temp_val.hour, &temp_val.min, &temp_val.temp) != 3) { fprintf(stderr, "%s: failed to scan line - %s", argv[0], line); return(EXIT_FAILURE); } printf("Data: "); print_temp(&temp_val); if ((new_temp = malloc(sizeof(*new_temp))) == 0) { fprintf(stderr, "%s: failed to allocate memory (%zu bytes)\n", argv[0], sizeof(*new_temp)); return(EXIT_FAILURE); } new_temp->hour = temp_val.hour; new_temp->min = temp_val.min; new_temp->temp = temp_val.temp; new_temp->next = 0; new_temp->prev = 0; add_to_list(&list, new_temp); /*print_list(&list);*/ } fclose(ifp); printf("\nData entry complete:\n"); print_list(&list); return(EXIT_SUCCESS); }