fscanf(filename, "[^:],%s:%d", cityState[29], Temperatures[29], &tnode_ptr->data[29]) != EOF)
#pragma
#define DISABLE_C4996_CRT_SECURE_NO_WARNINGS
/*********************************************************************************
** CIS 26B: Advanced C
******************
** Homework 2B:
** A Circular Doubly Linked List of Stacks
**********************************************************************************
This program...
Save the output as a comment at the end of the program.
**********************************************************
** Written By:Henry Barr III
** IDE: Visual Studio 2022
***************************************************************************/
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#define DUMMY_TRAILER '\177'
#ifdef _MSC_VER
#include <crtdbg.h> // needed to check for memory leaks (Windows only!)
#endif
//stack node
typedef struct tempstack TEMPSTACK;
struct tempstack
{
int* Temperatures;
struct tempstack* next;
};
//doubly linked list
typedef struct node NODE;
struct node
{
char* cityState;
struct tempstack* top;
struct tempstack* prev;
struct tempstack* data;
struct node* next;
int count;
};
int main(void)
{
NODE* init_dbllist(void);
void insert(NODE * node_ptr, char* cityState, int* Temperatures, int count);
void traverse_forw(NODE * node_ptr);
void traverse_back(NODE * node_ptr);
void traverse(NODE * node_ptr);
char cityState[29];
int Temperatures[29];
int count = 1;
NODE* tnode_ptr;
char Data[29];
tnode_ptr = &Data;
FILE* filename;
char fn[20] = { "temperatures.txt" };
char FN[20];
printf("Please enter a filename: ");
scanf("%s", FN);
filename = fopen(FN, "r");
int i = 0;
while (fscanf(filename, "%s:%d", cityState[29], Temperatures[29], &tnode_ptr->data[29]) != EOF) {
printf("%s, %d, %p", cityState[i], Temperatures[i], &tnode_ptr->data[i]);
i++;
}
NODE* node_ptr;
node_ptr = init_dbllist();
while (&filename != '\0') {
int i = 1;
insert(node_ptr, cityState, Temperatures, &count);
i++;
}
traverse(node_ptr);
#ifdef _MSC_VER
printf(_CrtDumpMemoryLeaks() ? "Memory Leak\n" : "No Memory Leak\n");
#endif
return 0;
}
/************************************************************************
Initialization of a linked list with two
sentinel nodes
*/
NODE* init_dbllist(void)
{
NODE* node_ptr;
int i = 0;
// allocate the first sentinel node
node_ptr = (NODE*)malloc(sizeof(NODE));
if (!node_ptr)
{
printf("Error in init_dbllist!\n");
exit(1);
}
node_ptr->cityState[i] = (char*)malloc(1);
if (!node_ptr->cityState[i])
{
printf("Error in init_dbllist!\n");
exit(1);
}
*node_ptr->cityState = '\0'; // dummy header value
// allocate the last sentinel node
node_ptr->next = (NODE*)malloc(sizeof(NODE));
if (!(node_ptr->next))
{
printf("Error in init_dbllist!\n");
exit(1);
}
node_ptr->next->cityState[i] = (char*)malloc(2);
if (!node_ptr->next->cityState[i])
{
printf("Error in init_dbllist!\n");
exit(1);
}
*node_ptr->next->cityState = DUMMY_TRAILER;
node_ptr->next->cityState[1] = '\0';
node_ptr->next->next = NULL;
node_ptr->prev = node_ptr;
return node_ptr;
}
void insert(NODE* node_ptr, char* cityState, int* Temperatures, int count)
{
NODE* curr = node_ptr->next;
NODE* prev = node_ptr;
NODE* newserv;
TEMPSTACK* newreq;
// look for citystate
while (strcmp(cityState, curr->cityState) > 0)
{
prev = curr;
curr = curr->next;
}
if (strcmp(cityState, curr->cityState) != 0) // Not found: new NODE!
{ // add a new node to the linked list
if ((newserv = (NODE*)malloc(sizeof(NODE))) == NULL)
{
printf("Fatal malloc error!\n");
exit(1);
}
if ((newserv->cityState = (char*)malloc(strlen(cityState) + 1)) == NULL)
{
printf("Fatal malloc error!\n");
exit(2);
}
strcpy(newserv->cityState, cityState);
newserv->next = curr;
prev->next = newserv;
newserv->top = NULL;
}
else // server found
{
newserv = curr;
}
// add a new node to the matching stack
if ((newreq = (TEMPSTACK*)malloc(sizeof(TEMPSTACK))) == NULL)
{
printf("Fatal malloc error!\n");
exit(3);
}
if ((newreq->Temperatures = (int*)malloc(strlen(Temperatures) + 1)) == NULL)
{
printf("Fatal malloc error!\n");
exit(4);
}
strcpy(newreq->Temperatures, Temperatures);
newreq->Temperatures = Temperatures;
newreq->next = NULL;
if (newserv->next == NULL)
{
newserv->prev = newserv->prev = newreq;
}
else
{
curr->prev->next = newreq;
curr->prev = curr->prev->next;
}
return 0;
}
/***************************************************
Traverses forward a circular doubly-linked
list with one sentinel node to print out the
contents of each node
*/
void traverse_forw(NODE* node_ptr)
{
putchar('\n');
node_ptr = node_ptr->next; // skip the dummy node
while (&node_ptr->data[0] != DUMMY_TRAILER)
{
printf("%s\n", node_ptr->data);
node_ptr = node_ptr->next;
}
return;
}
/***************************************************
Traverses backward a circular doubly-linked
list with one sentinel node to print out the
contents of each node
*/
void traverse_back(NODE* node_ptr)
{
putchar('\n');
node_ptr = node_ptr->prev; // skip the dummy node
while (&node_ptr->data[0] != DUMMY_TRAILER)
{
printf("%s\n", node_ptr->data);
node_ptr = node_ptr->prev;
}
return;
}
//Traverse Stack
void traverse(NODE* node_ptr)
{
NODE* tptr;
node_ptr = node_ptr->next; // skip dummy node
while (node_ptr->cityState[0] != DUMMY_TRAILER)
{
for (int i = 0; i < 19; i++)
{
printf("City, State: %s\n", node_ptr->cityState[i]);
}
printf("--------------------\n");
for (tptr = node_ptr->next; tptr != NULL; tptr = tptr->next)
{
printf("%-15p, %d\n", node_ptr->cityState, tptr->data);
}
}
}
//以下是温度.txt
Pennsylvania,Philadelphia:91
California,San Francisco:75
Nevada,Reno:108
Arizona,Flagstaff:81
California,Yreka:101
Arizona,Tucson:107
California,Los Angeles:78
California,Los Angeles:81
Pennsylvania,Pittsburgh:89
Oregon,Salem:90
California,Los Angeles:82
Arizona,Flagstaff:84
California,San Francisco:64
Oregon,Salem:83
California,San Francisco:68
Arizona,Tucson:99
California,Yreka:100
Arizona,Phoenix:109
Oregon,Portland:82
Arizona,Tucson:103
Oregon,Portland:79
Arizona,Phoenix:107
California,Cupertino:88
California,San Francisco:82
Arizona,Tucson:109
Oregon,Salem:85
Pennsylvania,Philadelphia:86
California,Los Angeles:97
Nevada,Reno:108
上述评论建议使用
fgets
,通常避免使用考虑到这一点:
// decl
//--------------------------------------------------
char line[256];
char state[64];
char city[64];
int temperature;
char *str; //iterator
// read line
//--------------------------------------------------
if (!fgets(line, sizeof line, file)) {
//either io error, or end of file,
//invoke ferror() and feof()
//act accordingly
}
// state
//--------------------------------------------------
//mark start of line
str = line;
//find comma to extract state
char *comma = strchr(str, ',');
if (!comma) {
//error, no point in continuing
}
//copy into state buffer
size_t state_size = comma - str;
//if (state_size >= sizeof state) -> error: state buffer too small
strncpy(state, str, state_size);
state[state_size] = '\0'; //make null-terminated
// city
//--------------------------------------------------
//mark first character after the comma
str = comma + 1;
//find colon to extract city
char *colon = strchr(str, ':');
if (!colon) {
//error, no point in continuing
}
//copy into city buffer
size_t city_size = colon - str;
//if (city_size >= sizeof city) -> error: city buffer too small
strncpy(city, str, city_size);
city[city_size] = '\0'; //make null-terminated
// temperature
//--------------------------------------------------
//mark first character after colon
str = colon + 1;
//convert remaining into temperature
temperature = atoi(str);
hint:代码很简单,包含适合外包以分开功能的经常性模式。