【问题标题】: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 系统

标签: c


【解决方案1】:

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

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

  2. 使用令牌作为 |作为第二级过滤(在其中你有 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”,这样更有意义

        【讨论】:

          猜你喜欢
          • 2018-10-20
          • 2015-02-06
          • 2012-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-19
          • 1970-01-01
          相关资源
          最近更新 更多