动态索引循环

时间:2013-09-19 20:41:13

标签: c embedded

我的微控制器UART有一个小缓冲区来处理数据,因此我想用小块发送数据,使用sprintf以字符串格式。 sample [k] =电压样本而不是随机数,并且需要逗号来分隔电压。

所以我想用随机数填充样本数组,而不是if() else语句。如何让sprintf()使用动态索引?

char str[512];
int sample[512];

printf("T1[");

int i = 0;
for (int j = 0; j < 64; j++)
{
    for(int k = 0; k < 8; k++)
    {
        sample[k] = rand() % 256;
    }

    sprintf( str, "%d,%d,%d,%d,%d,%d,%d,%d", sample[0],sample[1],sample[2],sample[3],sample[4],sample[5],sample[6],sample[7]);
    printf(str);
}

printf("]\r\n");

我可以做这样的事情

if (j == 0)
sprintf( str, "%d,%d,%d,%d,%d,%d,%d,%d", sample[0],sample[1],sample[2],sample[3],sample[4],sample[5],sample[6],sample[7]);
if (j == 1)
sprintf( str, "%d,%d,%d,%d,%d,%d,%d,%d", sample[8],sample[9],...

我试过了:

sprintf( str, "%d,%d,%d,%d,%d,%d,%d,%d", sample[i++],sample[i++],sample[i++],sample[i++],sample[i++],sample[i++],sample[i++],sample[i++]);

2 个答案:

答案 0 :(得分:1)

不幸的是,

sprintf( str, "%d,%d,%d,%d,%d,%d,%d,%d", sample[i++],sample[i++],sample[i++],
           sample[i++],sample[i++],sample[i++],sample[i++],sample[i++]);

不起作用;由于未指定评估函数参数的顺序,因此无法保证每个sample[i++]将从左到右进行评估,也不保证++的副作用在每个i++之后立即应用{评估{1}}。此代码的行为是 undefined ,这意味着结果是不可预测的。

不幸的是,没有好的方法可以在一次sprintf电话中做你要求的事情。您将必须明确指定每个索引,就像在

中一样
sprintf( str, "%d,%d,%d,%d,%d,%d,%d,%d", sample[0],sample[1],sample[2],sample[3],
           sample[4],sample[5],sample[6],sample[7]);

或者你必须写一些不同的东西,比如

strcpy( str, "" );
for ( size_t i = 0; i < 8; i++ )
{
  char tmp[4] = {0};
  char *empty = "";
  char *comma = ",";
  char *sep = empty;

  sprintf( tmp, "%s%d", sep, samples[i] );
  strcat( str, tmp );
  sep = comma;
}

<罢工>哎呀,我知道。坦率地说,最好只在一次sprintf调用中手动指定每个索引。

为了不给予更好的关注,我是正确的。如果您只需要一次打印一行8个样本到标准输出,那么很多更简单:

for ( j = 0; j < 64; j++ )
{
  printf( "%d", samples[ j * 8 ] );

  for ( k = 1; k < 8; k ++ )
  {
    printf( ",%d", sep, samples[ j * 8 + k ] );
  }
  putchar( '\n' );
}        

修改

for ( j = 0; j < 63; j++ )
{
    sprintf( str, "%d,%d,%d,%d,%d,%d,%d,%d,", 
      samples[ j * 8 ],     samples[ j * 8 + 1 ], samples[ j * 8 + 2 ],
      samples[ j * 8 + 3 ], samples[ j * 8 + 4 ], samples[ j * 8 + 5 ],
      samples[ j * 8 + 6 ], samples[ j * 8 + 7 ] );

    // send str
}        

sprintf( str, "%d,%d,%d,%d,%d,%d,%d,%d", 
  samples[ j * 8 ],     samples[ j * 8 + 1 ], samples[ j * 8 + 2 ],
  samples[ j * 8 + 3 ], samples[ j * 8 + 4 ], samples[ j * 8 + 5 ],
  samples[ j * 8 + 6 ], samples[ j * 8 + 7 ] );

// send str

最后一行的特例,因为我假设你不想在最后一个样本之后有一个尾随逗号。

答案 1 :(得分:0)

您可能会发现一次发送数据要容易得多;这实际上会占用更少的内存。例如

char str[10]; //FIXME verify this is enough for longest possible case
int samples[256];

//fill random data here

for (i = 0; i< 256; i++) {
    sprintf(str, "%d, ", samples[i]);  //could use snprintf for more safety
    #ifdef WINDOWS
      printf(str);
    #else
      UART_SEND_STRING(str);
    #endif
}