1

我必须从一个文本文件中创建一个双向链表,其中每一行都有时间和温度。例如每一行是这样的: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;

`

这是我的主文件:

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

1 回答 1

2

您想要int而不是int *在您的数据结构中,并且温度应该是 afloatdouble而不是 an 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()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

代码

#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);
}
于 2012-10-07T03:00:41.043 回答