帮助gcc不要警告不使用字符串文字格式字符串

时间:2009-08-27 16:27:29

标签: c gcc printf

我在C中创建一个函数,将索引值转换为字符串,这是对索引所代表的“字段”的详细描述。

所以,我有一个很好的数组,其中包含索引的所有详细描述。

要将它转储到缓冲区,我使用这样的代码

#define BUFFER_SIZE 40
void format_verbose(uint32_t my_index,
                    char     my_buffer[BUFFER_SIZE])
  {
    snprintf(mY_buffer, BUFFER_SIZE, "%s", MY_ARRAY[my_index].description);
  }

问题出现在某些情况下我需要在格式化时将一些其他字符串插入字符串中。所以我想要的是这样的(本例中的描述包含%s)。

void format_verbose_with_data(uint32_t my_index,
                              char     my_buffer[BUFFER_SIZE])
  {
    // ...
    snprintf(mY_buffer, BUFFER_SIZE, MY_ARRAY[my_index].description,
             some_string);
  }

我们的make文件设置为使用snprintf()警告(危险),警告被视为错误。所以,它不会编译。我想关闭这一行的警告,尽管它有点危险,我会控制字符串,我可以测试以确保它适用于它所调用的每个值。

或者,我很乐意以其他方式做到这一点,但我真的不想使用这个解决方案

void format_verbose_with_data(uint32_t my_index,
                              char     my_buffer[BUFFER_SIZE])
  {
    // ...
    snprintf(mY_buffer, BUFFER_SIZE, "%s%s%s"
    MY_ARRAY[my_index].description1, some_string,
    MY_ARRAY[my_index].description2);
  }

因为它使我的描述数组难看,特别是对于我不需要添加额外值的那些。

3 个答案:

答案 0 :(得分:4)

海湾合作委员会没有能力逐​​行关闭警告,所以我怀疑你运气不好。无论如何,如果你的编码标准说你不应该做某事,你就不应该找到打败它们的方法。

另一点,当你说:

void format_verbose(uint32_t my_index,
                    char     my_buffer[BUFFER_SIZE])

你真的在浪费你的时间打字 - 说:

更清晰,更惯用
void format_verbose(uint32_t my_index,
                    char     my_buffer[])

或:

void format_verbose(uint32_t my_index,
                    char     * my_buffer)

答案 1 :(得分:0)

经过一夜的思考,我计划通过自己查找%s标记手动分割输入字符串,然后将字符串separetley发送到snprintf()并使用自己的%s。对于这种情况,只允许使用一种类型的格式字符串,这样不那么繁琐,但是尝试完全重新实现printf()样式解析器会很糟糕。

void format_verbose_with_data(uint32_t my_index,
                              char     my_buffer[BUFFER_SIZE])
  {
    char    pre_description[BUFFER_SIZE];
    char    post_description[BUFFER_SIZE];
    int32_t offset = -1;

    offset = find_string(MY_ARRAY[my_index].description, "%s");
    ASSERT(offset >=0, "No split location!");
    // Use offset to copy the pre and post descriptions
    // Exercise left to the reader :-)
    snprintf(mY_buffer, BUFFER_SIZE, "%s%s%s"
             pre_description, some_string, post_description);
  }

答案 2 :(得分:0)

如果您使用snprintf()所做的只是复制字符串(看起来就是这种情况),即您所拥有的只有一个或多个"%s"作为格式字符串,你为什么不先使用strcpy(),也许先用strlen()检查来源的长度?

请注意strncpy(),而看起来就像一个好主意,并非如此。它总是用零填充目标缓冲区,如果源超过缓冲区大小,不会终止字符串