c-如何修复这个while循环,该循环用于在其内部填充结构的数组另一个结构的数组



我正在代码中填充一个结构数组,并在其中填充另一个结构阵列,但我陷入了循环中。我测试了每个分支和循环:它有效。但循环不起作用。

service_data _func中,我尝试分析文本并将其添加到结构中。

我在主函数中调用它,并将文本传递给它,然后尝试打印存储的值。我在循环中的每一步都使用print命令,它可以工作,但退出它不起作用。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct service_charge {
int from;
int to;
int charge;
int slap;
char percentage[5];
};
struct service {
int id;
int provider_id;
char name[30];
int price_type;
int min_value;
int max_value;
int sort_order;
char inquiry_required[5];
struct service_charge charge_arr[10];
};
struct service serv_data[8];
char text[1000]="{"success": true,"language": "en","action":
"GetServiceList","version": 1,"data": {"service_list":
[{"id": 4806,"provider_id": 581,"name": "Bill Payment (MG SC
AC)","price_type": 0,"min_value": 30,"max_value":
10000,"sort_order": 2,"inquiry_required":
true,"service_charge_list": [{"from": 1,"to": 547,"charge":
1,"slap": 1,"percentage": true1},{"from": 2,"to":
54875,"charge": 4,"slap": 5,"percentage": true1},,
{"from": 2,"to": 68945,"charge": 4,"slap":
5,"percentage": true2}]}";
void service_data_func (char text[]) {
int i=0;
int Wstart=0;
int Wend=0;
char name[19]= {0x20};
char name1[19]= {0x20};
int menunum=0;
int len;
len=strlen(text);
int menunum_charge=0;
while (1)//while ALL
{
if(i>=len) {
break;
}
if(text[i] == '"' && text[i+1] == 'i'&&
text[i+2] == 'd') {
while (1) { //while "id
if(text[i] == ':') {
Wstart=i+1;
Wend=0;
i++;
} else if(text[i] == ',' || text[i] == '}' ) {
Wend=i;
strncpy(name,text+Wstart,Wend-Wstart);
serv_data[menunum].id=atoi(name);
memset(name, 0, sizeof(name));
i++;
break;
} else {
i=i+1;
}
}//while id
} else if(text[i] == 's' && text[i+1] == 'e'&&
text[i+2] == 'r'&& text[i+3] == 'v'&& text[i+4] == 'i'&&
text[i+5] == 'c'&& text[i+6] == 'e'&& text[i+7] == '_'&& text[i+8]
== 'c'&& text[i+9] == 'h'&& text[i+10] == 'a'&& text[i+11] ==
'r'&& text[i+12] == 'g'&& text[i+13] == 'e'&& text[i+14] == '_'&&
text[i+15] == 'l'&& text[i+16] == 'i'&& text[i+17] == 's'&&
text[i+18] == 't') {
while (1)//while ALL
{
if(i>=len) {
break;
}
if(text[i] == 'f' && text[i+1] == 'r'&&
text[i+2] == 'o'&& text[i+3] == 'm') {
while (1) { //while from
if(text[i] == ':') {
Wstart=i+1;
Wend=0;
i++;
} else if(text[i] == ',' || text[i] == '}' ) {
Wend=i;
strncpy(name,text+Wstart,Wend-Wstart);
serv_data[menunum].charge_arr[menunum_charge].from=atoi(name);
memset(name, 0, sizeof(name));
i++;
break;
} else {
i=i+1;
}
}
} else {
i++;
}
}
} else {
i++;
}
}
}
int main()
{
service_data_func(text);
printf("%dn",serv_data[0].charge_arr[0].from);

return 0;
}

当您到达案例"service_charge_list"并提取您错过的值"from"时,添加一个break;以退出while (1)//while ALL,因此您继续搜索并到达下一个"from",即使该值与同一案例不对应,因此您将值1替换为2

例如,您可以替换:

if(text[i] == 'f' && text[i+1] == 'r'&&
text[i+2] == 'o'&& text[i+3] == 'm') {
while (1) { //while from
...
}
} else {
i++;
}

通过(其他可以删除)

if(text[i] == 'f' && text[i+1] == 'r'&&
text[i+2] == 'o'&& text[i+3] == 'm') {
while (1) { //while from
...
}
break;
} else {
i++;
}

现在执行打印1并对应于serv_data[0].id4806


附加备注:

(1) 类似的代码

if(text[i] == 's' && text[i+1] == 'e'&&
text[i+2] == 'r'&& text[i+3] == 'v'&& text[i+4] == 'i'&&
text[i+5] == 'c'&& text[i+6] == 'e'&& text[i+7] == '_'&& text[i+8]
== 'c'&& text[i+9] == 'h'&& text[i+10] == 'a'&& text[i+11] ==
'r'&& text[i+12] == 'g'&& text[i+13] == 'e'&& text[i+14] == '_'&&
text[i+15] == 'l'&& text[i+16] == 'i'&& text[i+17] == 's'&&
text[i+18] == 't')
...

不可读,难以维护,并且很容易包含错误。可以只是:

if (!strncmp(text + 1, "service_charge_list", 19))
...

当然,在较小的情况下也是如此。

(2) 在中给出尺寸是危险且无用的

char text[1000]="{"success": true,"language": "en","action":"GetServiceList","version": 1,"data": {"service_list":[{"id": 4806,"provider_id": 581,"name": "Bill Payment (MG SCAC)","price_type": 0,"min_value": 30,"max_value":10000,"sort_order": 2,"inquiry_required":true,"service_charge_list": [{"from": 1,"to": 547,"charge":1,"slap": 1,"percentage": true1},{"from": 2,"to":54875,"charge": 4,"slap": 5,"percentage": true1},,{"from": 2,"to": 68945,"charge": 4,"slap":5,"percentage": true2}]}";

只做

char text[]="{"success": true,"language": "en","action":"GetServiceList","version": 1,"data": {"service_list":[{"id": 4806,"provider_id": 581,"name": "Bill Payment (MG SCAC)","price_type": 0,"min_value": 30,"max_value":10000,"sort_order": 2,"inquiry_required":true,"service_charge_list": [{"from": 1,"to": 547,"charge":1,"slap": 1,"percentage": true1},{"from": 2,"to":54875,"charge": 4,"slap": 5,"percentage": true1},,{"from": 2,"to": 68945,"charge": 4,"slap":5,"percentage": true2}]}";

const char * text="{"success": true,"language": "en","action":"GetServiceList","version": 1,"data": {"service_list":[{"id": 4806,"provider_id": 581,"name": "Bill Payment (MG SCAC)","price_type": 0,"min_value": 30,"max_value":10000,"sort_order": 2,"inquiry_required":true,"service_charge_list": [{"from": 1,"to": 547,"charge":1,"slap": 1,"percentage": true1},{"from": 2,"to":54875,"charge": 4,"slap": 5,"percentage": true1},,{"from": 2,"to": 68945,"charge": 4,"slap":5,"percentage": true2}]}";

(3) 在中

char name[19]= {0x20};
char name1[19]= {0x20};

没有理由将名称的第一个字符设置为",并且name1未使用,可以删除

(4) 在这种情况下:

if(text[i] == '"' && text[i+1] == 'i'&&
text[i+2] == 'd') {
while (1) { //while "id
if(text[i] == ':') {
...

你再次测试前3个字符,最好在while 之前进行i += 3;

(5) 你复制类似的代码来搜索关键字和提取值,你不能继续这样做,对于所有的情况,你管理的少数情况已经太多了,使用的专用功能

(6) kiran Biradar在一句话中说,如果text是无效的,那么有几种无限循环的情况最终会产生对text的访问,以及相关的未定义行为