如何将给定的字符串解析为结构变量数组
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”,这样更有意义
【讨论】:
以上是关于如何将给定的字符串解析为结构变量数组的主要内容,如果未能解决你的问题,请参考以下文章