2013-12-05 3 views
2
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| 

Выше это сообщение, поступающее с одного сервера в виде одной строки. Теперь я хочу проанализировать его и сохранить в структуре для обработки на языке C.Как разобрать данную строку в массив структурной переменной

Здесь для одной строки P (Period) может быть много строк C (класса). '|' это полевой разделитель, который следует игнорировать при хранении в структуре. Здесь число строк C (класс) не фиксировано для P.

Может ли кто-нибудь предложить мне на C, как я должен объявлять структуры и анализировать и хранить эти поля в нем. Согласно моей догадке, я должен будет объявить массив структуры во время выполнения для строк класса (C), поскольку он не является фиксированным. Исправлено одно: размер строки P (Period) всегда равен 17 байтам (или charector), исключая размер трубы (|) и C (класс), равный 61 символу, за исключением трубы (|............................... . или код

+0

Я не уверен. Если я получу ваш вопрос, но почему бы вам не использовать список ссылок с P как узел заголовка, а остальные C как обычные узлы и добавить любые детали, которые вы хотите добавить в объявление структуры? – codeomnitrix

+0

Но до этого он должен получить данные в строке, не так ли? – Srikanth

+0

Дорогой codeomnitrix, может у, пожалуйста, помогите мне с некоторыми примерами деклараций структуры. Это действительно даст мне некоторую основную идею ... Спасибо заранее – user3064342

ответ

0

Есть несколько уровней синтаксического анализа для этой строки

  1. Используйте маркер, как P/C для делать первый уровень фильтрации

  2. Используйте маркер, как | в качестве второго уровня фильтрации (Внутри, где у вас есть H/Y и т. Д., Которые вы также должны учитывать при копировании его на элементы структуры).

Соответственно, вы можете иметь декларацию структуры.

Вы можете посетить эту статью strtok usage

+0

Я собирался предложить использовать strtok в сочетании с конечным автоматом.Но учитывая, что структура каждой записи «P» и «C» выглядит исправленной, я думаю, что ваше решение лучше. –

0

Здесь вы идете -

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

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

После этого вы можете использовать

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

Rest является просто синтаксический анализ строки.

Надеюсь, это поможет.

1
#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; 
} 
0
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 
}; 
0

Наиболее важная часть надежно разбора входа, после этого, интерпретации, проверки и организация предварительно структурированных данных является ветром, я сделал только жесткая часть (обработку ввода) ниже

#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; 
} 

код выше в значительной мере опирается на арифметику указателей

* редактирование: переименовать «перевалы» до «строки» и «ячейки» на «перевалы», имеет больше смысла

Смежные вопросы