2017-09-27 10 views
-1

ファイルを読み込み、入力を二重リンクリストにトークン化して、それを処理します。すなわち、ソート、それを書きなさい...等区切られたフラットファイルを構造体の二重リンクリストにパースする

 
[email protected]:~/Documents/testproject$ cat test.txt 
2017-07-25,14:50:02:477, 12104,932,HOST, log message 1111111111111111111111111111 
2017-07-26,14:50:02:478, 12104,932,HOST, log message 22222222222222222222222222222222222222 
2017-07-27,14:50:03:095, 12104,932,HOST, log message 3333333333333333 
2017-07-28,14:50:04:587, 12104,932,HOST, log message 444444444444444444444444444444444444444444444 
2017-07-29,14:50:04:587, 12104,932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr 
junk to be parsed out 
more junk 1234567 

しかし私がリストを歩くとき、各ノードは最後のエントリを含んでいます。私がどこに間違っているのかを知っている人は誰ですか? をcreatenewnode()関数に追加しました。正しい文字列がstructノードに設定されているようです。

 
[email protected]:~/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$$4RRrr 
0x557237b1a720 1986300429 2017-07-29 14:50:04:587 932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr 
0x557237b1a6e0 1986300429 2017-07-29 14:50:04:587 932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr 
0x557237b1a6a0 1986300429 2017-07-29 14:50:04:587 932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr 
0x557237b1a250 1986300429 2017-07-29 14:50:04:587 932,HOST, log message blah blah blahb 1234455e56456546 test test test ERrroRRRrrr$$4RRrr 

コード:

/* 
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; 
} 

答えて

1

あなたのエラーは、

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

ラインにして割り当てるメモリが関数にローカルな機能struct node* createnewnode(char* ds, char* ts, char* msg)です。関数を終了すると消えますので、後の行は

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を拡大し、より少なく柔軟です。たとえば、メッセージは256文字以上必要です。

または、ファイル内のエントリの長さを測定し、それに応じてメモリを割り当てて、メッセージのヒープと固定長が同じである場合は、日付とタイムストリングのスタックを使用します。クリーンアップ時にヒープメモリを解放することを忘れないでください!

+0

あなたの助けていただきありがとうございます。ご覧のとおり、私はCノブです。私は#1のソリューションを使用しましたが、今は正しく動作しています。 – Matt