问题
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