gpt4 book ai didi

c - 将分隔的平面文件解析为结构的双向链表

转载 作者:行者123 更新时间:2023-11-30 19:07:46 24 4
gpt4 key购买 nike

我正在尝试编写一个 C 程序来读取文件,将输入标记为双向链表,并对其进行处理,即:对其进行排序,对其进行遍历,对其进行写入...等

md@ubuntu:~/Documents/testproject$ cat test.txt2017-07-25,14:50:02:477, 12104,932,HOST, log message 11111111111111111111111111112017-07-26,14:50:02:478, 12104,932,HOST, log message 222222222222222222222222222222222222222017-07-27,14:50:03:095, 12104,932,HOST, log message 33333333333333332017-07-28,14:50:04:587, 12104,932,HOST, log message 4444444444444444444444444444444444444444444442017-07-29,14:50:04:587, 12104,932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrrjunk to be parsed outmore junk 1234567

However when I walk the list each node contains the last entry. Any suggests on where I'm going wrong here ? I've added printf in the createnewnode() function, and it seem that the correct strings are being set in the struct node.

md@ubuntu:~/Documents/testproject$ ./doubly test.txt*****CREATE NODE*****(2017-07-25,14:50:02:477,932,HOST, log message 1111111111111111111111111111*****CREATE NODE*****(2017-07-26,14:50:02:478,932,HOST, log message 22222222222222222222222222222222222222*****CREATE NODE*****(2017-07-27,14:50:03:095,932,HOST, log message 3333333333333333*****CREATE NODE*****(2017-07-28,14:50:04:587,932,HOST, log message 444444444444444444444444444444444444444444444*****CREATE NODE*****(2017-07-29,14:50:04:587,932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr*****PRINT LINKED LIST*****0x557237b1a760 1986300429 2017-07-29 14:50:04:587 932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr0x557237b1a720 1986300429 2017-07-29 14:50:04:587 932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr0x557237b1a6e0 1986300429 2017-07-29 14:50:04:587 932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr0x557237b1a6a0 1986300429 2017-07-29 14:50:04:587 932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr0x557237b1a250 1986300429 2017-07-29 14:50:04:587 932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr

Code:

/*
Parse a delimited log file and tokenized values in a doubly linked list.
Do stuff with this doubly linked list of structures (ie: sort by time....etc)

*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <locale.h>
#include <errno.h>

#define __USE_XOPEN
#include <time.h>
#include <sys/time.h>

#define LINESIZE 1024

//Linked List structure
struct node
{
int jobid;
char* datestring;
char* timestring;
char* message;
struct node *prev; //previous node
struct node *next; //next node
};
typedef struct node node;

node *head = NULL; //declar pointer beginning of linked list

//prototypes for linked list functions
struct node* createnewnode(char* ds, char* ts, char* msg); //create a new node and return a pointer to it
void insert_at_head(char* ds, char* ts, char* msg);
void print_elements();
static void clean();
int parseFile(char* fname);
char **strsplit(const char* str, const char* delim, size_t* numtokens);
int lensum(char **input);


/* DOUBLY LINKED LISTS */


//Node Generator
struct node* createnewnode(char* ds, char* ts, char* msg)
{
node *newnode = malloc(sizeof(node)); //allocate memory on the heap and create a new node structure

//copy strings to local variables. Desperate hope to get this working, but probably not needed
char tds[LINESIZE], tts[LINESIZE],tmsg[LINESIZE];

strcpy(tds, ds);
strcpy(tts, ts);
strcpy(tmsg, msg);

#ifdef DEBUG
printf("*****CREATE NODE*****(%s,%s,%s\n",tds,tts,tmsg);
#endif


newnode->datestring = tds;
newnode->timestring = tts;
newnode->message = tmsg;

srand(time(NULL));
newnode->jobid = rand(); //set to random value to see if it changes between iterations

newnode->prev = NULL;
newnode->next = NULL;

return newnode;
}


//Insert Node at the beginning of the list
void insert_at_head(char* ds, char* ts, char* msg)
{

node *newnode = createnewnode(ds, ts, msg);

//If this is the first element being added to the linked list
if (head == NULL)
{
head = newnode;
return;
}
head->prev = newnode;
newnode->next = head;
head = newnode;
}

//print_elements() in linked list from the head to the tail (end)
void print_elements()
{
node *ptmp = head; //beginning of the list
if (ptmp == NULL)
{
printf("Warning: No elements in this list\n");
return;
}

#ifdef DEBUG
printf("\n*****PRINT LINKED LIST*****\n");
#endif

while(ptmp != NULL)
{
printf("%p %d %s %s %s\n",ptmp, ptmp->jobid, ptmp->datestring, ptmp->timestring, ptmp->message );
ptmp = ptmp->next;
}
return;
}


static void clean()
{
node *temp = NULL;

while(head != NULL)
{
temp = head;
head = head->next;
free(temp);
}
}



/* PARSE FILE */
int parseFile(char* fname)
{
FILE *in = fopen(fname, "r");
char line[LINESIZE];
struct tm date;
const char delim[] = ",";
char *tok;
char dbuf[LINESIZE], tbuf[LINESIZE], mbuf[LINESIZE];

while (fgets(line, sizeof(line), in) != NULL) {


if ((void *)strptime(line,"%Y-%m-%d",&date) != NULL)
{
tok = strtok(line, delim);
strcpy((char*)dbuf, tok);

tok = strtok(NULL, delim);
if (NULL != tok)
{
strcpy((char*)tbuf, tok);
tok = strtok(NULL,delim);
}
tok = strtok(NULL,"\n");

if (NULL != tok)
{
strcpy((char*)mbuf, tok);
}

insert_at_head(dbuf, tbuf, mbuf);

}

}
fclose(in); //close file pointer
return 0;
}



int main(int argc, char const *argv[])
{

parseFile("test.txt");
print_elements();
clean();

return 0;
}

最佳答案

您的错误在于函数struct node* createnewnode(char* ds, char* ts, char* msg)您在该行分配的内存

char tds[LINESIZE], tts[LINESIZE],tmsg[LINESIZE];

是函数的局部变量。当您离开该功能时它就会消失,因此后面的行

    newnode->datestring = tds;
newnode->timestring = tts;
newnode->message = tmsg;

不会做你想做的事。

您可以在堆上保留一些内存,例如:

    //char tds[LINESIZE], tts[LINESIZE],tmsg[LINESIZE];

char *tds = malloc(LINESIZE); // can be fixed if length is fixed
char *tts = malloc(LINESIZE); // can be fixed if length is fixed
char *tmsg = malloc(LINESIZE); // the message is probably variable, so measure it

但您必须稍后释放该内存。

或者通过更改struct来保留一些堆栈内存,例如:

struct node
{
int jobid;
char datestring[100];
char timestring[100];
char message[256];
struct node *prev; //previous node
struct node *next; //next node
};

但这会极大地扩大struct,并且灵 active 较差。例如,该消息可能需要超过 256 个字符。

或者使用混合方法,如果日期和时间字符串始终具有相同的固定长度,则使用堆栈来存储日期和时间字符串,并通过测量文件中条目的长度并相应地分配内存来使用堆来存储消息。清理时不要忘记释放堆内存!

关于c - 将分隔的平面文件解析为结构的双向链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46457665/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com