【问题标题】:Ellipsis issue with va_start() on nRF52840nRF52840 上 va_start() 的省略号问题
【发布时间】:2019-01-23 05:54:39
【问题描述】:

我想使用 va_start 从省略号中检索我的参数。

这是我的代码:

char str[256];
void nrf_log_flash(bool is_to_save, char * log, ...){
    va_list args;
    va_start(args, log);
    int ret = vsprintf(str, log, args);
    if(is_to_save){
         sprintf(str, "%s : %s\n", nrf_cal_get_time_string(false), log);
         //my_nrf_log_add(str, strlen(str));
    }
    NRF_LOG_INFO("%s", log);
    NRF_LOG_INFO("%s", str);
    NRF_LOG_INFO("%d", ret);
    va_end(args);

}

这是我的使命:

nrf_log_flash(true, "button %d pressed, %u, %x, %c", 2, 3658, 0xca, 'a');

但是我的 va_list 是空的。我做错了什么?

【问题讨论】:

  • 你是什么意思,你如何检查“你的 va_list 是空的”?
  • 此代码示例不完整。请在 vsprintf 之后直接检查 str 的简单 printf 以验证错误不在之后的代码中。
  • 如果is_to_save 为真,那么您会立即覆盖刚刚打印的内容

标签: c ellipsis nrf52


【解决方案1】:

行后

int ret = vsprintf(str, log, args);

您的 str 变量包含格式化的字符串(例如 str 是“按下按钮 2,3658,ca,a”。但是,您的下一句将覆盖此数据。当您调用 sprintf 时,并使用 'log 覆盖 str 处的数据' 格式的变量(“按下按钮 %d,%u,%x,%c”)

if(is_to_save){
     //THIS CODE OVERWRITE YOUR STR BUFFER
     sprintf(str, "%s : %s\n", nrf_cal_get_time_string(false), log);
     //my_nrf_log_add(str, strlen(str));
}

顺便说一句,建议使用 snprint 和 vsnprintf 以避免缓冲区溢出。由于格式包含“%s”,因此可能会打印一个大于 256 字节的大字符串。

【讨论】:

  • 它工作得很好,但我不明白为什么我的 str 被覆盖,当我调用 vsprintf 时,标签被参数替换并存储到 str 对吗?因此,当我在下一行调用 sprintf 时,它如何将标签放回 str ?
  • @Firerazzer 当您调用sprintf 时,替换值在str 中,log 现在已完成。我猜你需要像sprintf( datedStr, "%s : %s\n", nrf...(), str); 这样的东西来创建一个包含时间戳和strnew 字符串(datedStr)(log 的内容带有替换值)。您还应该注意,如果这些消息中的任何一条太长(大约 256 个字符),您就会遇到问题。
  • @TripeHound Ho 是的......现在很明显......感谢您的时间和耐心!是的,我用 snprintf() 替换了 sprintf(),用 vsnprintf() 替换了 vsprintf(),谢谢提示
猜你喜欢
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
  • 2020-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多