创建从C文本文件的双向链表 [英] Creating Doubly Linked List from text file on C

查看:254
本文介绍了创建从C文本文件的双向链表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须做出一个双向链表出在每一行有一个时间和温度的文本文件中。例如前每行是这样的:23.69 12:48

所以,我无法将数据放入一个双向链表。我不知道如何实现它。所以我做了元素的typedef结构的数组,并希望我能与数组的第一个元素开始,指向旁边的数组的第二个元素。这是我有...

因此​​,这里是为双向链表我的头文件:

 #包括LT&;&stdio.h中GT;
typedef结构tempdata_ {    INT *小时;
    INT *分钟;
    INT *温度;
    结构tempdata_ *接下来的;
    结构tempdata_ * preV;
} TempData的;teypdef结构templist_ {    TempData的*头;
    TempData的*尾;
    INT大小;
} templist;

`

下面是我的主文件:

 的#include<&stdio.h中GT;
 #包括linkedlist.h
INT主(INT ARGC,CHAR *的argv [])
 {
    FILE * IFP,* OFP;
    // CHAR outputFilename [] =的argv [2];
    INT SIZE = 1;
    TempData的tempdata1 [100];
    TempData的*温度,*电流= NULL;    如果(ARGC!= 2)/ * ARGC应该是3正确执行* /
    {
        / *我们打印的argv [0]假设它是程序名* /
        输出(用法:%s的文件名的argv [0]);
    }
    其他
    {
        //我们假设的argv [1]是打开一个文件名
        IFP = FOPEN(的argv [1],R);        / * FOPEN返回0,NULL指针,失败* /
        如果(IFP == 0)
        {
             的printf(无法打开文件\\ n);
        }
        其他
        {
            // OFP =的fopen(outputFilename,W);            / *读取小时,分钟,tempeture整数和小数的温度和
            打印出来的屏幕上和被赋予输出文件。
            我们不需要这个打印功能,但我刚出具有的功能做一些事情* /            而(的fscanf(IFP,%D:%D%D,&安培; tempdata1 [SIZE]·小时,和放大器; tempdata1 [SIZE] .min,&安培; tempdata1 [SIZE] .tempI,&安培; tempdata1 [ SIZE] .tempD)!= EOF){
                 的printf(下称tempeture在%D%D:%d个\\ N,tempdata1 [SIZE] .tempI,tempdata1 [SIZE] .tempD,tempdata1 [SIZE]·小时,tempdata1 [SIZE] .min);                    / * fprintf中(OFP的tempeture在%D%D:%d个\\ N,tempdata1 [SIZE] .tempI,tempdata1 [SIZE] .tempD,tempdata1 [SIZE]·小时,tempdata1 [SIZE] .min); * /
                SIZE ++;
 } FCLOSE(IFP);
 // FCLOSE(OFP);
        }
    }
    的getchar();
 }


解决方案

您想 INT ,而不是为int * 在你的数据结构,温度应该是浮动双击而非 INT (这大大简化了输入;否则,同时处理26.09和26.9正确是相当困难,当你用两个整数输入温度)。

  typedef结构的TempData的TempData;结构的TempData
{
    诠释小时;
    INT分钟;
    浮温度;
    TempData的*下一;
    TempData的* preV;
};

您将头更有说服力无错字:

  typedef结构templist templist;结构templist
{
    TempData的*头;
    TempData的*尾;
    INT大小;
} 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

我得到的产量为:

 数据: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数据录入完成:
负责人:0x102800BB0,尾:0x102800C90,尺寸:8
温度:0x102800BB0:12:29 26.34
温度:0x102800BD0:28.23 13:32
温度:0x102800BF0:28.56 14:20
温度:0x102800C10:29.10 15:30
温度:0x102800C30:30.45 16:18
温度:0x102800C50:28.12 17:20
温度:0x102800C70:26.98 18:20
温度:0x102800C90:24.12 19:35

code

 的#include<&ASSERT.H GT;
#包括LT&;&errno.h中GT;
#包括LT&;&inttypes.h GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;typedef结构的TempData的TempData;结构的TempData
{
    诠释小时;
    INT分钟;
    浮温度;
    TempData的*下一;
    TempData的* preV;
};typedef结构templist templist;结构templist
{
    TempData的*头;
    TempData的*尾;
    INT大小;
};静态无效ADD_TO_LIST(templist *名单,TempData的* new_temp)
{
    断言(名单!= 0);
    断言(列表 - >大小> = 0);
    断言((列表 - >头== 0安培;&安培;列表 - >尾== 0安培;&安培;列表 - >大小== 0)||
           (列表 - >头= 0&安培;!&安培;列表 - >尾= 0&安培;!&安培;列表 - >!大小= 0));
    new_temp-> preV =列表 - >尾;
    new_temp->接着= 0;
    列表 - >大小++;
    如果(列表 - >头== 0)
        列表 - >头= new_temp; / *新的列表* /
    其他
        列表 - > tail->接下来= new_temp; / *添加到列表尾部* /
    列表 - >尾= new_temp;
}静态无效print_temp(常量TempData的*数据)
{
    的printf(%d个:%D%6.2f \\ n,DATA->小时线,数据>分线,数据>温度);
}静态无效print_list(常量templist *名单)
{
    常量TempData的*数据;
    断言(名单!= 0);
    断言(列表 - >大小> = 0);
    断言((列表 - >头== 0安培;&安培;列表 - >尾== 0安培;&安培;列表 - >大小== 0)||
           (列表 - >头= 0&安培;!&安培;列表 - >尾= 0&安培;!&安培;列表 - >!大小= 0));
    的printf(团长:0X%PRIXPTR尾巴:为0x%PRIXPTR,大小数:%d \\ n,
            (uintptr_t形式)列表 - >头(类型uintptr_t)列表 - >尾巴,列表 - >大小);
    对于(数据=列表 - >头;数据= 0;!数据=数据 - >接下来)
    {
        的printf(温度:0X%PRIXPTR:(uintptr_t形式)的数据);
        print_temp(数据);
    }
}INT主(INT ARGC,字符** argv的)
{
    FILE * IFP;
    templist列表= {NULL,NULL,0};
    焦线[2048];    如果(的argc!= 2)
    {
        fprintf中(标准错误,用法:%s的文件名\\ n,argv的[0]);
        回报(EXIT_FAILURE);
    }    IFP = FOPEN(的argv [1],R);    如果(IFP == 0)
    {
        fprintf中(标准错误,%S:无法打开文件%s(%D:%S)\\ n,argv的[0],ARGV [1],错误号,字符串错误(错误));
        回报(EXIT_FAILURE);
    }    而(与fgets(线,的sizeof(线),IFP)!= 0)
    {
        TempData的temp_val;
        TempData的* new_temp;        如果(sscanf的(行,%D:%D%F!,&安培; temp_val.hour,&安培; temp_val.min,&安培; temp_val.temp)= 3)
        {
            fprintf中(标准错误,%S:无法扫描线 - %S的argv [0],线);
            回报(EXIT_FAILURE);
        }
        的printf(数据:);
        print_temp(安培; temp_val);
        如果((new_temp =的malloc(sizeof的(* new_temp)))== 0)
        {
            fprintf中(标准错误,%S:无法分配内存(%祖字节)\\ n,argv的[0],sizeof的(* new_temp));
            回报(EXIT_FAILURE);
        }
        new_temp->小时= temp_val.hour;
        new_temp->分= temp_val.min;
        new_temp-> TEMP = temp_val.temp;
        new_temp->接着= 0;
        new_temp-> preV = 0;
        ADD_TO_LIST(安培;列表,new_temp);
        / * print_list(安培;清单); * /
    }
    FCLOSE(IFP);    的printf(\\ n数据录入完成:\\ n);    print_list(安培;清单);
    回报(EXIT_SUCCESS);
}

I have to make a doubly linked list out of a text file in which every row has a time and temperature. Fore example each row is like this: 12:48 23.69

So I'm having trouble putting the data into a doubly linked list. I don't know how to implement it. So I did an array of the typedef struct of the elements and was hoping I could start with the first element of the array and point the next to the second element of the array. Here's what I have...

So here's my header file for the doubly linked list:

#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;

`

Here's my main file:

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

解决方案

You want int and not int * in your data structure, and the temperature should be a float or double rather than an int (which greatly simplifies the input; otherwise, handling both 26.09 and 26.9 correctly is rather hard when you use two integers to input the temperature).

typedef struct tempdata tempdata;

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

Your header would be more convincing without the typo:

typedef struct templist templist;

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

Having an array of tempdata structures is actually more sensible than a doubly linked list, but it defeats the object of the exercise, I fear. You should probably be dynamically allocating the structures as you need them. I'd use fgets() plus sscanf(), but you are checking the result from fscanf() — which is good — but you could get stuck if the data is malformed because the file is not at EOF but doesn't contain a digit where fscanf() needs one. You should be checking that the return value is 3 (one for each converted field), and if not, breaking the loop.

To create a list, you will need a variable of type templist somewhere, appropriately initialized.

I've assembled the program below from your outline. Given the data file:

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

The output I got was:

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

Code

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

这篇关于创建从C文本文件的双向链表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆