【问题标题】:snprintf + Pebblesnprintf + Pebble
【发布时间】:2014-01-08 15:00:04
【问题描述】:

我正在为 Pebble 进行开发,但起步并不顺利。

我正在尝试用 2 个字符串和 2 个值填充 text_layer,如下所示:

等待平均:3 最大:5

由于 Pebble SDK 不支持 malloc,因此我无法使用 sprintf,因此我只能使用 snprintf。以下代码只打印“4”:

srand(time(NULL));
int average = (rand()%6)+1; 
int maximum = average + 2;
static char *avgText="WAIT AVG: ";
static char *maxText="MAX: ";
snprintf(labelText,sizeof(avgText) + sizeof(average) + sizeof(maxText) + sizeof(maximum),"%s %d %s %d",avgText,average,maxText,maximum);

任何帮助将不胜感激。我知道我可以创建 4 个单独的 TextLayers,但这对我来说是最后的手段。

【问题讨论】:

  • 为什么sprintf 依赖于malloc
  • @CoryNelson 有一点,snprintf 只需要一个额外的参数n 来防止缓冲区溢出,因为n 是要填充的最大缓冲区容量
  • @Siidheesh 这太冗长了。 sizeof(char) 按标准保证为1
  • @CoryNelson,这里是多余的,但如果他迁移到宽字符类型,包含 sizeof(the type used) 会很有用:),但不确定 Pebble SDK 是否支持宽字符
  • @CoryNelson - 我猜他们最初省略了sprintf 以避免膨胀,然后在避免缓冲区溢出的可疑前提下让步并添加snprintf。它没有! stackoverflow.com/questions/12275381/strncpy-vs-sprintf

标签: c sizeof strlen printf pebble-sdk


【解决方案1】:

您只是在使用 snprintf 错误。 ;-)

第二个参数(您尝试计算的结果很糟糕)是您要打印到的字符数组的长度,不是您要写入的字符数。

这样的事情应该可以工作:

char labelText[64]; // Is this big enough?
snprintf(labelText, 64,"%s %d %s %d",avgText,average,maxText,maximum);

【讨论】:

    【解决方案2】:

    sizeof(avgText)sizeof(maxText) 是指针的大小,而不是数组的大小。参见例如here。将您的代码更改为

    static char avgText[] = "WAIT AVG: ";
    static char maxText[] = "MAX: ";
    

    为了使它们成为数组。

    编辑:

    进一步注意,sizeof(average)average 内部覆盖的字节大小,不是十进制表示会消耗多少字节。

    编辑2:

    正如罗迪的回答所说,计算我们想要的大小并将该大小作为实际缓冲区大小传递给snprintf 是错误的。但是,如果有一个合理的上限,我们可以计算我们想要的大小(例如,使用 32 位 int,10 个字节(没有 0 终止符)总是足够的,但也许您可以在你的用例):

    char labelText [
            sizeof avgText - 1 + 10 +
            sizeof maxText - 1 + 10 + 3 + 1
    ];
    /* sizeof avgText counts the 0-terminator, so does sizeof maxText, hence
    the -1, two times 10 for the `int` (or any reasonable upper bound you have),
    3 spaces and the 0-terminator. */
    

    你甚至可以使用sprintf。使用snprintf,您可以:

    snprintf(labelText, sizeof labelText,"%s %d %s %d", avgText, average, maxText, maximum);
    

    HTH

    【讨论】:

    • 你不需要这样做:运行时不需要计算输出字符串的长度。
    • @Roddy:我在哪里说的?
    • @maifso。我的观点是没有必要进行 OP 正在尝试的(错误的)计算。没有。要输出的字符数并不重要,但缓冲区的大小。 (在我之前的评论中忽略“运行时”)
    • 是的,我同时看到了你的回答。等一下,我马上修改。
    【解决方案3】:

    正确阅读snprintf()man page。它说,第二个参数size 用于引用要写入的number of bytes

    sizeof (avgText)sizeof(maxText) 不会在这里工作。它指的是pointer 的大小,而不是它所拥有的数组的length。也许您想使用strlen() 作为字符串长度。

    【讨论】:

      【解决方案4】:

      这样就成功了:

      srand(time(NULL));
      static char labelText[]="WAIT AVG: xxxxx MAX: xxxxxx";
      int average = (rand()%6)+1; 
      int maximum = average + 2;
      static char avgText[]="WAIT AVG: ";
      static char maxText[]="MAX: ";
      snprintf(labelText,sizeof(labelText),"%s %d %s %d",avgText,average,maxText,maximum);
      text_layer_set_text(waitField,labelText);
      

      谢谢大家

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-18
        • 2015-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多