如何将给定的字符串解析为结构变量数组

Posted

技术标签:

【中文标题】如何将给定的字符串解析为结构变量数组【英文标题】:How to parse the given string into array of structure variable 【发布时间】:2013-12-05 05:09:27 【问题描述】:
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(Class) 行。 '|'是字段分隔符,在存储到结构中时应忽略。这里的 C(Class) 行数对于 P 是不固定的。

谁能建议我用 C 语言,我应该如何声明结构并解析这些字段并将其存储到其中。根据我的猜测,我将不得不在运行时为类(C)行声明结构数组,因为它不是固定的。一件事是固定的:P(Period)行大小始终是 17 字节(或字符),不包括管道(|)和 C(类)行大小是 61 个字符,不包括管道(|。亲爱的,请任何人帮助我用 C 逻辑或代码。

【问题讨论】:

我不确定如果我得到你的问题,但你为什么不使用链接列表 P 作为头节点,其余 C 作为普通节点,并添加你想在结构声明中添加的任何细节? 但在这之前,他必须得到字符串中存在的数据不是吗? 亲爱的codeomnitrix,你能帮我一些示例结构声明吗..它真的会给我一些基本的想法......提前谢谢 @user3064342:如果您想与任何人联系,请使用 @User_name。这就是这里的 SO 系统 【参考方案1】:

这个字符串有多个解析级别

    使用token作为P/C进行第一级过滤

    使用令牌作为 |作为第二级过滤(在其中你有 H/Y 等,在将其复制到结构成员时也需要考虑)。

因此你可以有结构声明。

您可以访问这篇文章strtok usage

【讨论】:

我打算将 strtok 与状态机结合使用。但鉴于每个“P”和“C”记录的结构看起来是固定的,我认为您的解决方案更好。【参考方案2】:

给你-

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 只是解析字符串。

我希望这会有所帮助。

【讨论】:

【参考方案3】:
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 
;

【讨论】:

【参考方案4】:
#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;

【讨论】:

【参考方案5】:

最关键的部分是安全地解析输入,之后,预结构化数据的解释、验证和组织变得轻而易举,我只做了下面最难的部分(输入处理)

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

上面的代码在很大程度上依赖于指针算法

*edit:将“cols”重命名为“rows”,将“cells”重命名为“cols”,这样更有意义

【讨论】:

以上是关于如何将给定的字符串解析为结构变量数组的主要内容,如果未能解决你的问题,请参考以下文章

将字符串解析为 c 样式字符数组的结构

如何使用字符串为不同大小的数组设计结构?

算法和数据结构解析-5 : 滑动窗口问题

算法和数据结构解析-5 : 滑动窗口问题

实验十二:字符串和结构

如何将给定的字符串格式解析为 dd-MMM-yyyy hh:mm:ss:aa?