Creating Doubly Linked List from text file on C

吃可爱长大的小学妹 提交于 2019-12-24 09:04:03

问题


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

回答1:


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


来源:https://stackoverflow.com/questions/12765713/creating-doubly-linked-list-from-text-file-on-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!