Question

Salut je l'ai écrit un code basé sur une exigence.

(field1_6) (field2_30) (field3_16) (field4_16) (field5_1) (field6_6) (field7_2) (field8_1 ) ..... ceci est un godet (8 champs) de données. nous allons recevoir 20 seaux à un moment signifie totalement 160 champs. je dois prendre les valeurs de field3, field7 & fields8 en fonction de condition prédéfinie. si Teh argument d'entrée est N puis prendre les trois champs du 1er seau et si elle est Y i besoin de prendre les trois champs d'un autre seau autre que 1er un. si argumnet est Y, alors je dois analyser tous les 20 seaux les uns après les autres et le contrôle le premier champ de la benne n'est pas égal à 0 et s'il est vrai, alors les trois champs chercher de ce seau et de sortie. J'ai écrit le code et son beau travail ..mais pas non plus si confiant qu'il est effctive. je suis peur d'un accident time.Please certains suggèrent ci-dessous est le code.

int CMI9_auxc_parse_balance_info(char *i_balance_info,char  *i_use_balance_ind,char *o_balance,char *o_balance_change,char *o_balance_sign
)
{
  char *pch = NULL;
  char *balance_id[MAX_BUCKETS] = {NULL};
  char balance_info[BALANCE_INFO_FIELD_MAX_LENTH] = {0};
  char *str[160] = {NULL};
  int i=0,j=0,b_id=0,b_ind=0,bc_ind=0,bs_ind=0,rc;
  int total_bukets ;
  memset(balance_info,' ',BALANCE_INFO_FIELD_MAX_LENTH);
  memcpy(balance_info,i_balance_info,BALANCE_INFO_FIELD_MAX_LENTH);
  //balance_info[BALANCE_INFO_FIELD_MAX_LENTH]='\0';
  pch = strtok (balance_info,"*");
  while (pch != NULL && i < 160)
  {
     str[i]=(char*)malloc(strlen(pch) + 1);
     strcpy(str[i],pch);
     pch = strtok (NULL, "*");
     i++;
  }
total_bukets  = i/8  ;
  for (j=0;str[b_id]!=NULL,j<total_bukets;j++)
  {
  balance_id[j]=str[b_id];
  b_id=b_id+8;
  }
  if (!memcmp(i_use_balance_ind,"Y",1))
  {
     if (atoi(balance_id[0])==1)
     {
        memcpy(o_balance,str[2],16);
        memcpy(o_balance_change,str[3],16);
        memcpy(o_balance_sign,str[7],1);
        for(i=0;i<160;i++)
        free(str[i]);
        return 1;
     }
     else
     {
        for(i=0;i<160;i++)
        free(str[i]);
      return 0;
     }
  }
  else if (!memcmp(i_use_balance_ind,"N",1))
  {
      for (j=1;balance_id[j]!=NULL,j<MAX_BUCKETS;j++)
      {
        b_ind=(j*8)+2;
        bc_ind=(j*8)+3;
        bs_ind=(j*8)+7;
       if (atoi(balance_id[j])!=1 && atoi( str[bc_ind] )!=0)
       {
        memcpy(o_balance,str[b_ind],16);
        memcpy(o_balance_change,str[bc_ind],16);
        memcpy(o_balance_sign,str[bs_ind],1);
        for(i=0;i<160;i++)
        free(str[i]);
        return 1;
       }
      }
     for(i=0;i<160;i++)
     free(str[i]);
    return 0;
  }
 for(i=0;i<160;i++)
 free(str[i]);
return 0;
}
Était-ce utile?

La solution

J'ai eu du mal à lire votre code, mais FWIW j'ai ajouté quelques commentaires, HTH:

// do shorter functions, long functions are harder to follow and make errors harder to spot
// document all your variables, at the very least your function parameters
// also what the function is suppose to do and what it expects as input
int CMI9_auxc_parse_balance_info
(
  char *i_balance_info,
  char *i_use_balance_ind,
  char *o_balance,
  char *o_balance_change,
  char *o_balance_sign
)
{
  char *balance_id[MAX_BUCKETS] = {NULL};
  char balance_info[BALANCE_INFO_FIELD_MAX_LENTH] = {0};
  char *str[160] = {NULL};
  int i=0,j=0,b_id=0,b_ind=0,bc_ind=0,bs_ind=0,rc;
  int total_bukets=0; // good practice to initialize all variables

  //
  // check for null pointers in your arguments, and do sanity checks for any
  // calculations
  // also move variable declarations to just before they are needed
  //

  memset(balance_info,' ',BALANCE_INFO_FIELD_MAX_LENTH);
  memcpy(balance_info,i_balance_info,BALANCE_INFO_FIELD_MAX_LENTH);
  //balance_info[BALANCE_INFO_FIELD_MAX_LENTH]='\0';  // should be BALANCE_INFO_FIELD_MAX_LENTH-1

  char *pch = strtok (balance_info,"*"); // this will potentially crash since no ending \0

  while (pch != NULL && i < 160)
  {
    str[i]=(char*)malloc(strlen(pch) + 1);
    strcpy(str[i],pch);
    pch = strtok (NULL, "*");
    i++;
  }
  total_bukets  = i/8  ;
  // you have declared char*str[160] check if enough b_id < 160
  // asserts are helpful if nothing else assert( b_id < 160 );
  for (j=0;str[b_id]!=NULL,j<total_bukets;j++)
  {
    balance_id[j]=str[b_id];
    b_id=b_id+8;
  }
  // don't use memcmp, if ('y'==i_use_balance_ind[0]) is better
  if (!memcmp(i_use_balance_ind,"Y",1))
  {
    // atoi needs balance_id str to end with \0 has it?
    if (atoi(balance_id[0])==1)
    {
      // length assumptions and memcpy when its only one byte
      memcpy(o_balance,str[2],16);
      memcpy(o_balance_change,str[3],16);
      memcpy(o_balance_sign,str[7],1);
      for(i=0;i<160;i++)
        free(str[i]);
      return 1;
    }
    else
    {
      for(i=0;i<160;i++)
        free(str[i]);
      return 0;
    }
  }
  // if ('N'==i_use_balance_ind[0]) 
  else if (!memcmp(i_use_balance_ind,"N",1))
  {
    // here I get a headache, this looks just at first glance risky. 
    for (j=1;balance_id[j]!=NULL,j<MAX_BUCKETS;j++)
    {
      b_ind=(j*8)+2;
      bc_ind=(j*8)+3;
      bs_ind=(j*8)+7;
      if (atoi(balance_id[j])!=1 && atoi( str[bc_ind] )!=0)
      {
        // length assumptions and memcpy when its only one byte
        // here u assume strlen(str[b_ind])>15 including \0
        memcpy(o_balance,str[b_ind],16);
        // here u assume strlen(str[bc_ind])>15 including \0
        memcpy(o_balance_change,str[bc_ind],16);
        // here, besides length assumption you could use a simple assignment
        // since its one byte
        memcpy(o_balance_sign,str[bs_ind],1);
        // a common practice is to set pointers that are freed to NULL.
        // maybe not necessary here since u return
        for(i=0;i<160;i++)
          free(str[i]);
        return 1;
      }
    }
    // suggestion do one function that frees your pointers to avoid dupl
    for(i=0;i<160;i++)
      free(str[i]);
    return 0;
  }
  for(i=0;i<160;i++)
    free(str[i]);
  return 0;
}

Une technique utile lorsque vous souhaitez accéder à des décalages dans un tableau est de créer une structure qui mappe la mise en page de la mémoire. Ensuite, vous lancez votre pointeur sur un pointeur de struct et d'utiliser les membres de struct pour extraire l'information au lieu de vos différentes années memcpy

Je vous suggère également revoir vos paramètres à la fonction en général, si vous placez chacun d'eux dans une struct vous avez un meilleur contrôle et rend la fonction plus lisible par exemple.

int foo( input* inbalance, output* outbalance )

(ou quoi que ce soit que vous essayez de le faire)

Autres conseils

Mon sentiment est que ce code est très fragile. Il peut bien fonctionner quand une bonne entrée donné (je ne propose pas de service de check la chose pour vous), mais si on leur donne des entrées incorrectes, il sera soit crash and burn ou donner des résultats trompeurs.

Avez-vous testé pour les entrées inattendues? Par exemple:

  • Supposons i_balance_info est nulle?
  • Supposons i_balance_info est ""?
  • Supposons qu'il y ait moins de 8 éléments dans la chaîne d'entrée, ce que cette ligne de code va faire?

    memcpy(o_balance_sign,str[7],1);
    
  • Supposons que que l'élément dans str [3] est inférieure à 16 caractères de long, ce sera cette ligne de code faire?

    memcpy(o_balance_change,str[3],16);
    

Mon approche de l'écriture de code tel serait de protéger contre toutes ces éventualités. Au moins j'ajouter des instructions assert (), je généralement écrire la validation des entrées explicites et renvoyer des erreurs quand il est mauvais. Le problème ici est que l'interface semble ne pas tenir compte de toute possibilité qu'il pourrait y avoir une mauvaise entrée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top