Reputation: 21
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
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
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
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
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
Reputation: 445
There are multiple parsing levels for this string
Use token as P/C for doing the first level of filtering
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