0

我的微控制器 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++]);
4

2 回答 2

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++。此代码的行为是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

最后一行的特殊情况,因为我假设您不希望在最后一个样本之后使用尾随逗号。

于 2013-09-19T21:02:51.493 回答
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
}
于 2013-09-21T15:38:47.197 回答