Как это исправить, пока цикл используется для заполнения массива структуры внутри него другим массивом структуры - PullRequest
0 голосов
/ 31 января 2019

Я заполняю массив структуры внутри кода, а внутри него - другой массив структуры, но я застреваю в цикле.Я проверил каждую ветку и цикл: это работает.Но цикл не работает.

В service_data _func Я пытаюсь проанализировать текст и добавить его в структуру.

Я вызываю его в основной функции, передаю текст и пытаюсьчтобы распечатать сохраненное значение, я использую команду печати на каждом шаге в цикле, он работает, но выход из него не работает.

#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("%d\n",serv_data[0].charge_arr[0].from);


    return 0;
}

1 Ответ

0 голосов
/ 31 января 2019

Когда вы доходите до дела "service_charge_list" и извлекаете значение "из", вы пропустили добавление break; для выхода из while (1)//while ALL, поэтому вы продолжаете поиск и достигаете следующего "из" дажеэто не соответствует тому же случаю, поэтому вы замените значение 1 на 2 .

Например, вы можете заменить:

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

by ( else может быть удалено)

            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].id со значением 4806


Дополнительные примечания:

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

нет причин устанавливать первый символ из name to '', а name1 не используется и может быть удалено

(4) В таких случаях:

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

             if(text[i] == ':') {
               ...

вы тестируете сновапервые 3 символа, лучше сделать i += 3; до того, как

(5) Вы дублируете похожие коды для поиска по ключевым словам и для извлечения значений, вы не можете продолжать делать это во всех случаях, этоЭто уже слишком для тех немногих дел, которыми вы управляете, используйте для этого выделенные функции

(6) Киран Бирадар говорит, что в вашем замечании есть несколько случаев бесконечных циклов, которые в конечном итоге создают доступ из text со связанным неопределенным поведением, если текст недействителен

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...