我该如何改进这段代码?我不喜欢这么多的ifs

时间:2014-11-25 18:55:18

标签: c arduino

我有以下代码,但我觉得很脏..

我不想写这么多ifs,然后在每个if中重复输入代码..

关于如何改进此代码的任何想法?

char obj[5];
strlcpy(obj, &jarr[i], arr[i]);
if( !strcmp( obj, "led_r" ) ){
    i++;
    strlcpy( obj, &jarr[i], arr[i] );
    red_brightness = atoi( obj );

    Serial.print(" RED: ");
    Serial.println( red_brightness );
}
if( !strcmp( obj, "led_g" ) ){
    i++;
    strlcpy( obj, &jarr[i], arr[i] );
    green_brightness = atoi( obj );

    Serial.print(" GREEN: ");
    Serial.println( green_brightness );
}
if( !strcmp( obj, "led_b" ) ){
    i++;
    strlcpy( obj, &jarr[i], arr[i] );
    blue_brightness = atoi( obj );

    Serial.print(" BLUE: ");
    Serial.println( blue_brightness );
}

6 个答案:

答案 0 :(得分:5)

在此之前的其他答案也很好。这个答案的优点是你可以将选项名称更改为任何东西,它仍然可以工作。您还可以将此类选项解析扩展为更大的选项集。

// Assuming these are globals.
int red_brightness, green_brightness, blue_brightness;

// Use this array to help you parse.
static const struct {
    const char *optionName;
    int        *brightness;
    const char *label;
} ledOptions[] = {
    { "led_r", &red_brightness,   " RED: "   },
    { "led_g", &green_brightness, " GREEN: " },
    { "led_b", &blue_brightness,  " BLUE: "  },
};

// A handy macro for later.
#define DIM(array)  (sizeof(array) / sizeof(array[0]))

...

// Now in your actual code:    
strlcpy(obj, &jarr[i], arr[i]);
for (j=0;j<DIM(ledOptions);j++) {
    if( !strcmp( obj, ledOptions[i].optionName ) ){
        i++;
        strlcpy( obj, &jarr[i], arr[i] );
        *ledOptions[i].brightness = atoi( obj );

        Serial.print(ledOptions[i].label);
        Serial.println(*ledOptions[i].brightness);
    }
}

答案 1 :(得分:2)

将前4个字符与“led_”进行比较,确保其长度为5,然后打开第五个字符。将其余代码重构为函数。

答案 2 :(得分:2)

公共代码可以从if语句

中计算出来

您可以将switch语句用于字符串

中唯一更改的字符
switch(obj[4]) {
    case 'r':
        Serial.println("RED: " + red_brightness );
    case 'g':
        Serial.println("GREEN: " + green_brightness );
    case 'b':
        Serial.println("BLUE: " + blue_brightness );
}

答案 3 :(得分:0)

这就是我想出的。免责声明,我还没有尝试编译/运行它。

for (int i=0; i<6; i++)
{
   i++;
   int b = atoi( &jarr[i] );
   switch (i)
   {
     case 1:
        Serial.print(" RED: ");
        red_brightness = b;
        break;
     case 3: 
        Serial.print(" GREEN: ");
        green_brightness = b;
        break;
     case 5:
        Serial.print(" BLUE: ");
        blue_brightness = b;
        break;
     default:
        break;
   }
   Serial.println(b);
}

想要打印的值是在奇数索引处的&amp; jarr []中。

答案 4 :(得分:0)

这里只是为了好玩我的个人方法...

#ifndef ARDUINO
#include <string.h>
#include <stdio.h>

/* PART of code derived from question but unspecified in code . done to be able to compile */

// this is not specified in question 
//   either it a char jarr[1024] but then why do we iterate on char ( i++ would go to next char and not to next word )
//   either it is a char* jar[6] but then we access its char * content with jarr[i] and not with &jarr[i]
//char * jarr[6];
// this look like to be size of each argument.
//int arr[6];

/*
TEST vectors
 */

char * jarr0[] = { "led_r", "200", "led_g", "100", "led_b", "150" };
int arr0[] = { 5, 3, 5,3, 5,3 };

char * jarr1[] = { "led_g", "200", "led_r", "100", "led_b", "150" };
int arr1[] = { 5, 3, 5,3, 5,3 };

char * jarr2[] = { "lgd_g", "200", "ged_r", "100", "led_b", "150" };
int arr2[] = { 5, 3, 5,3, 5,3 };

int red_brightness = 0;
int blue_brightness = 0;
int green_brightness = 0;

/* end of unspecified PART */
#endif

/*real code *

/* use indirection */
struct led_color_map {
  int * color_brightness_p;
  const char * color_name;
  char key;
} led_color[] = {
  {&red_brightness,"RED",'r'},
  {&green_brightness,"GREEN",'g'},
  {&blue_brightness,"BLUE",'b'}
};


enum { RED_IDX=0, GREEN_IDX, BLUE_IDX };

// for perf test
int miss = 0;

#ifdef ARDUINO
void led_setup()
#else
  void led_setup(char * jarr[], int arr[])
#endif
{

  char* obj=NULL;
  int i=0;
  int offset=0;

  for (i=0; i <6; i+=2)
    {
      obj=jarr[i];
      // test 'led_' prefix with reverse statistical letter apparence
      // which is 'l' then 'd' then 'e' , guessing that '_' can be used in other words ... 
      if ( ( obj[0] == 'l' ) && ( obj[2] == 'd' ) && (obj[1] == 'e' ) && (obj[3] == '_') )
    {
      int idx=0;
      for ( idx = 0; idx <= BLUE_IDX; idx ++)
        {
          int rolling_idx = (idx + offset) % ( BLUE_IDX + 1 );
          struct led_color_map * color_found = &led_color[rolling_idx]; 
          if ( color_found->key == obj[4] )
        {
          char ivalue[32];
          if ( arr[i+1] < sizeof(ivalue) )
            {
              #ifdef ARDUINO
              strlcpy(ivalue, jarr[i+1], arr[i+1]);
              #else
              strncpy(ivalue, jarr[i+1], arr[i+1]);
              #endif
              {
            int brightness = atoi( ivalue );
            *(color_found->color_brightness_p) = brightness;
            #ifdef ARDUINO
            Serial.print( color_found->color_name );
            Serial.println( *color_brightness );
            #else
            printf(" %s :%i\n", color_found->color_name, brightness);
            #endif
              }
              offset=(rolling_idx + 1) % ( BLUE_IDX + 1 ); // try with next color first next time.
              break;
            }
        }
          else
        {
          miss ++;
          printf("miss %i wrong color order expected %s\n",miss, led_color[rolling_idx].color_name);
        }
        }     
    }
      else
    {
      miss ++;
      printf("miss %i wrong variable expected led_%c\n", miss, led_color[offset % ( BLUE_IDX + 1 )].key);
    }
    }

}

#ifndef ARDUINO
int main(int argc, char ** argv)
{

led_setup(jarr0, arr0);
 printf("test0 : miss %i\n",miss);

miss=0;
led_setup(jarr1, arr1);
 printf("test1 : miss %i\n",miss);

miss=0;
led_setup(jarr2, arr2);
 printf("test2 : miss %i\n",miss);

}
#endif

gcc led.c ./a.out

 RED :200
 GREEN :100
 BLUE :150
test0 : miss 0
miss 1 wrong color order expected RED
 GREEN :200
miss 2 wrong color order expected BLUE
 RED :100
miss 3 wrong color order expected GREEN
 BLUE :150
test1 : miss 3
miss 1 wrong variable expected led_r
miss 2 wrong variable expected led_r
miss 3 wrong color order expected RED
miss 4 wrong color order expected GREEN
 BLUE :150
test2 : miss 4

答案 5 :(得分:0)

char obj[5];
strlcpy(obj, &jarr[i], arr[i]);
int *brightness;
String ostr();
if( !strcmp( obj, "led_r" ) ){
 ostr = " RED: ";
 brightness = red_brightness;
}
if( !strcmp( obj, "led_g" ) ){
 ostr = " GREEN: ";
 brightness = green_brightness;
}
if( !strcmp( obj, "led_b" ) ){
 ostr = " BLUE: ";
 brightness = blue_brightness;
}
i++;
strlcpy( obj, &jarr[i], arr[i] );
*brightness = atoi( obj );
Serial.print(ostr);
Serial.println(*brightness);