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

从C上的文本文件创建双链表,c,scanf,doubly-linked-list,C,Scanf,Doubly Linked List,我必须从文本文件中创建一个双链接列表,其中每一行都有时间和温度。例如,每行是这样的:12:48 23.69 所以我很难将数据放入双链接列表中。我不知道如何实施它。所以我做了一个元素的typedef结构数组,希望能从数组的第一个元素开始,然后将下一个元素指向数组的第二个元素。这是我所拥有的 下面是我的双链接列表的头文件: #include<stdio.h> typedef struct tempdata_{ int *hour; int *min; int *

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

所以我很难将数据放入双链接列表中。我不知道如何实施它。所以我做了一个元素的typedef结构数组,希望能从数组的第一个元素开始,然后将下一个元素指向数组的第二个元素。这是我所拥有的

下面是我的双链接列表的头文件:

#include<stdio.h>
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;
#包括
typedef结构tempdata_{
整数*小时;
int*min;
内部*温度;
结构tempdata_*next;
结构tempdata_*prev;
}临时数据;
teypdef结构模板_{
tempdata*头;
tempdata*tail;
整数大小;
}圣殿骑士;
`

这是我的主要文件:

 #include <stdio.h>
 #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();
 }
#包括
#包括“linkedlist.h”
int main(int argc,char*argv[])
{
文件*ifp,*ofp;
//char outputFilename[]=argv[2];
int SIZE=1;
tempdata tempdata1[100];
tempdata*temp,*current=NULL;
如果(argc!=2)/*argc应为3以正确执行*/
{
/*我们打印argv[0],假设它是程序名*/
printf(“用法:%s文件名”,argv[0]);
}
其他的
{
//我们假设argv[1]是要打开的文件名
ifp=fopen(argv[1],“r”);
/*fopen在失败时返回0,即空指针*/
如果(ifp==0)
{
printf(“无法打开文件\n”);
}
其他的
{
//ofp=fopen(输出文件名,“w”);
/*读取小时、分钟、温度整数和温度小数,以及
在屏幕上和给定的输出文件上打印出来。
我们不需要这个打印功能,但我只是让这个功能做些什么*/
而(fscanf(ifp,“%d:%d%d.%d”,&tempdata1[SIZE].hour,&tempdata1[SIZE].min,&tempdata1[SIZE].tempI,&tempdata1[SIZE].tempD)!=EOF){
printf(“温度为%d.%d,位于%d:%d\n”,tempdata1[SIZE].tempI,tempdata1[SIZE].tempD,tempdata1[SIZE].hour,tempdata1[SIZE].min);
/*fprintf(ofp,“温度为%d.%d,位于%d:%d\n”,tempdata1[SIZE].tempI,tempdata1[SIZE].tempD,tempdata1[SIZE].hour,tempdata1[SIZE].min)*/
大小++;
}
fclose(ifp);
//fclose(ofp);
}
}
getchar();
}

您希望在数据结构中使用
int
而不是
int*
,并且温度应该是
float
double
而不是
int
(这大大简化了输入;否则,当使用两个整数输入温度时,正确处理26.09和26.9是相当困难的).

如果没有输入错误,您的标题将更具说服力:

typedef struct templist templist;

struct templist
{
    tempdata *head;
    tempdata *tail;
    int size;
} templist;
拥有一个
tempdata
结构数组实际上比一个双链表更明智,但我担心它会破坏练习的目标。您可能应该根据需要动态分配结构。我会使用
fgets()
plus
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
代码
#包括
#包括
#包括
#包括
#包括
#包括
typedef结构tempdata tempdata;
结构tempdata
{
整小时;
int-min;
浮子温度;
tempdata*下一步;
tempdata*prev;
};
typedef结构templast templast;
结构圣殿骑士
{
tempdata*头;
tempdata*tail;
整数大小;
};
静态无效添加到列表(模板列表*列表,临时数据*新临时)
{
断言(列表!=0);
断言(列表->大小>=0);
断言((列表->头==0&&列表->尾==0&&列表->大小==0)||
(列表->头!=0和列表->尾!=0和列表->大小!=0));
新建临时->上一个=列表->尾部;
新建温度->下一步=0;
列表->大小++;
如果(列表->标题==0)
列表->标题=新建\u temp;/*新建列表*/
其他的
列表->尾部->下一步=新建\u temp;/*添加到列表尾部*/
列表->尾部=新的温度;
}
静态无效打印温度(常数温度数据*数据)
{
printf(“%d:%d%6.2f\n”,数据->小时,数据->分钟,数据->温度);
}
静态无效打印列表(const templist*列表)
{
常数tempdata*数据;
断言(列表!=0);
断言(列表->大小>=0);
断言((列表->头==0&&列表->尾==0&&列表->大小==0)||
(列表->头!=0和列表->尾!=0和列表->大小!=0));
printf(“头:0x%“PRIXPTR”,尾:0x%“PRIXPTR”,大小:%d\n”,
(uintptr\u t)列表->头部,(uintptr\u t)列表->尾部,列表->大小);
对于(数据=列表->标题;数据!=0;数据=数据->下一步)
{
printf(“温度:0x%”PRIXPTR:“,(uintptpr_t)数据);
打印温度(数据);
}
}
int main(int argc,字符**argv)
{
文件*ifp;
模板列表={NULL,NULL,0};
字符行[2048];
如果(argc!=2)
{
fprintf(stderr,“用法:%s文件名\n”,argv[0]);
返回(退出失败);
}
ifp=fopen(argv[1],“r”);
如果(ifp==0)
{
fprintf(stderr,“%s:无法打开文件%s(%d:%s)\n”、argv[0]、argv[1]、errno、strerror(errno));
返回(退出失败);
}
while(fgets(line,sizeof(line),ifp)!=0)
{
临时数据临时值;
tempdata*新温度;
如果(sscanf(行“%d:%d%f”、&temp\u val.hour、&temp\u val.min、&temp\u val.temp)!=3)
{
fprintf(stderr,“%s:未能扫描行-%s”,argv[0],行);
返回(退出失败);
}
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 <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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