user3064342
user3064342

Reputation: 21

How to parse the given string into array of structure variable

P|20131120|20131120
C|F|350.0|50.0|350.0|16.67|50.0|16.67|1400.0|Y|15.0|
C|H|610.3|87.19|610.3|29.06|87.19|29.06|2441.2|Y|15.0|
C|L|1386.0|198.0|1386.0|66.0|198.0|66.0|5544.0|Y|15.0|
C|Z|1286.0|183.71|1286.0|61.24|183.71|61.24|5144.0|Y|15.0|

P|20131121|20131121
C|A|323.65|46.24|323.65|15.41|46.24|15.41|1294.6|Y|15.0|
C|B|323.65|46.24|323.65|15.41|46.24|15.41|1294.6|Y|15.0|
C|D|365.65|52.24|365.65|17.41|52.24|17.41|1462.6|Y|15.0|
C|E|365.65|52.24|365.65|17.41|52.24|17.41|1462.6|Y|15.0|

Above is the message coming from one server as a single string. Now i want to parse it and store in a structure for the processing in C language.

Here for one P(Period) row, there can be many C(Class) rows. '|' is field delimiter which should be ignored while storing into the structure. Here the number of C(Class) rows are not fixed for a P.

Can anybody suggest me in C, how should i declare the Structures and parse and store these fields into it. As per my guess i will have to declare the structure array at run time for class(C) rows because it is not fixed. One thing is fixed: P(Period) row size is always 17 byte (or charector) excluding pipe(|) and C(Class) row size is 61 character excluding pipe(|. Dear All, can please anybody help me in C logic or code.

Upvotes: 2

Views: 1399

Answers (5)

alexgirao
alexgirao

Reputation: 895

The most critical part is safely parsing the input, after that, interpretation, validation and organization of the pre-structured data is a breeze, I made only the hard part (input handling) below

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char *data =
  "P|20131120|20131120\n"
  "C|F|350.0|50.0|350.0|16.67|50.0|16.67|1400.0|Y|15.0|\n"
  "C|H|610.3|87.19|610.3|29.06|87.19|29.06|2441.2|Y|15.0|\n"
  "C|L|1386.0|198.0|1386.0|66.0|198.0|66.0|5544.0|Y|15.0|\n"
  "C|Z|1286.0|183.71|1286.0|61.24|183.71|61.24|5144.0|Y|15.0|\n"
  "\n"
  "P|20131121|20131121\n"
  "C|A|323.65|46.24|323.65|15.41|46.24|15.41|1294.6|Y|15.0|\n"
  "C|B|323.65|46.24|323.65|15.41|46.24|15.41|1294.6|Y|15.0|\n"
  "C|D|365.65|52.24|365.65|17.41|52.24|17.41|1462.6|Y|15.0|\n"
  "C|E|365.65|52.24|365.65|17.41|52.24|17.41|1462.6|Y|15.0|\n"
  ;

struct columns
{
  char *cols[12]; /* 16 pointers */
} rows[100];  /* bss, all zero */

#define N_COLS (sizeof(struct columns)/sizeof(char*))
#define N_ROWS (sizeof(rows)/sizeof(struct columns))

int main(void)
{
  char *rowsdata, *s;
  char **curcol  = rows->cols;
  char **lastcol = rows->cols + N_COLS;
  int row, i;

  rowsdata = s = strdup(data);
  if (rowsdata == 0) {
    perror("strdup");
    exit(1);
  }

  for (row=0; row < N_ROWS; s++) {
    if (*s == '|') {
      *s = 0;
      if (++curcol == lastcol) {
        puts("error: too much columns");
        exit(1);
      }
    } else if (*s == '\n') {
      *s = 0;
      row++;
      curcol  = (rows + row)->cols;
      lastcol = (rows + row)->cols + N_COLS;
    } else if (*curcol == 0) {
      *curcol = s;
    } else if (*s == 0) break;
  }

  /* do your logic here
   */

  for (i=0; i<row; i++) {
    curcol = (rows + i)->cols;
    lastcol = (rows + i)->cols + N_COLS;
    while (*curcol && curcol < lastcol) {
      printf("[%s]", *curcol);
      curcol++;
    }
    printf("\n");
  }

  /* free rowsdata only when done with rows
   */
  free(rowsdata); rowsdata = 0;

  return 0;
}

the code above relies heavily on pointer arithmetic

*edit: rename from 'cols' to 'rows' and 'cells' to 'cols', makes more sense

Upvotes: 1

user2134086
user2134086

Reputation:

#include <stdio.h>
#include <string.h>

#define MAX_CLASSES 100
#define MAX_PERIODS 100

struct Class{
  char a, i;
  float b,c,d,e,f,g,h,j;
};

struct Period{
  char date1[10], date2[10];
  struct Class classes[MAX_CLASSES];
};

struct Period periods[MAX_PERIODS];

int main(void){
  //use sscanf to parse the data
  //for example, (assuming data is in char *s),
  //sscanf(s, "P|%s|%s\n", periods[0].date1, periods[0].date2);
  return 0;
}

Upvotes: 1

Naga Venkatesh
Naga Venkatesh

Reputation: 99

struct c_struct
{
    char c_content[61];
    struct c_strcut *next_c_strcut; //pointer to next class
};

struct PC_struct
{
    char p_content[17];
    struct c_struct *c_head; // pointer to first node
    struct PC_struct *PC_struct; // pointer to next pc 
};

Upvotes: 1

codeomnitrix
codeomnitrix

Reputation: 4249

Here you go -

struct node{
    char startChar, endChar;
    float numArr[8];
    struct node *next;
}

struct headerNode{
   int num1, num2;
   struct node *first;
}

After that you can make use of

createList() //create a blank list with header node.
createNode() //a C node everytime you need it.

Rest is merely parsing the string.

I hope this will help.

Upvotes: 1

Srikanth
Srikanth

Reputation: 445

There are multiple parsing levels for this string

  1. Use token as P/C for doing the first level of filtering

  2. Use token as | as second level of filtering ( Inside which youi have H/Y etc which you need to take into consideration as well while copying it to structure members).

Accordingly you can have structure declartion .

You can visit this article strtok usage

Upvotes: 1

Related Questions