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

帮助gcc不要警告不要使用字符串文字格式字符串,c,gcc,printf,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, "

我在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

我们的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);
  }

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

GCC无法逐行关闭警告,所以我怀疑您运气不好。无论如何,如果你的编码标准说你不应该做什么,你就不应该想办法打败他们

还有一点,当你说:

void format_verbose(uint32_t my_index,
                    char     my_buffer[BUFFER_SIZE])
你真的是在浪费时间打字——说:

void format_verbose(uint32_t my_index,
                    char     my_buffer[])
或:


GCC无法逐行关闭警告,因此我怀疑您运气不好。无论如何,如果你的编码标准说你不应该做什么,你就不应该想办法打败他们

还有一点,当你说:

void format_verbose(uint32_t my_index,
                    char     my_buffer[BUFFER_SIZE])
你真的是在浪费时间打字——说:

void format_verbose(uint32_t my_index,
                    char     my_buffer[])
或:


经过一晚上的思考,我计划手动将输入字符串分割开来,方法是自己查找%s标记,然后将字符串separatley与它们自己的%s一起发送到snprintf()。在这种情况下,只允许使用1种格式字符串,这就不那么繁重了,但是尝试完全重新实现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);
  }

经过一晚上的思考,我计划手动将输入字符串分割开来,方法是自己查找%s标记,然后将字符串separatley与它们自己的%s一起发送到snprintf()。在这种情况下,只允许使用1种格式字符串,这就不那么繁重了,但是尝试完全重新实现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);
  }

如果您使用
snprintf()
所做的只是复制字符串(似乎是这样),即您所拥有的只是一个或多个
“%s”
作为格式字符串,那么为什么不先使用
strcpy()
,或者使用
strlen()
来检查源代码的长度呢


请注意,
strncpy()
,虽然看起来是个好主意,但事实并非如此。它总是用零填充目标缓冲区,如果源超出缓冲区大小,则不会以null终止字符串。

如果您使用
snprintf()
所做的一切都是复制字符串(似乎是这样),即您所拥有的只是一个或多个
“%s”
作为格式字符串,为什么不使用
strcpy()
,也许先用
strlen()
检查源代码的长度


请注意,
strncpy()
,虽然看起来是个好主意,但事实并非如此。它总是用零填充目标缓冲区,如果源缓冲区大小超过缓冲区大小,则不使用null终止字符串。

可能是C没有对传入的缓冲区大小提供任何保护,但我不同意在您可以清楚地看到代码假定缓冲区大小是正确的情况下,忽略缓冲区大小更为明显。清晰在旁观者的眼中:-)另外,我可能应该保护自己不受短缓冲区的影响,要么使用定义的错误行为,要么使用断言。编码标准问题的一个例子是类型转换-我们允许它们防止编译器警告,这使得发生的事情更加明显。可能是C没有对传入的缓冲区大小提供任何保护,但我不同意忽略缓冲区大小更为明显,当你能清楚地看到代码时,你会认为它是正确的。清晰在旁观者的眼中:-)另外,我可能应该保护自己不受短缓冲区的影响,要么使用定义的错误行为,要么使用断言。编码标准问题的一个例子是类型转换——我们允许它们阻止编译器警告,这使得发生的事情更加明显。编辑以删除检查字符串缓冲区长度的愚蠢尝试。当然,这不会起作用,除非缓冲区初始化为所有非零。编辑以删除愚蠢的尝试检查字符串缓冲区的长度。当然,这不会起作用,除非缓冲区初始化为非零。谢谢你的回答!我很久以前就放弃了这项工作:-(。无论如何,我不确定这两个函数之间有多大区别。复制或打印,我仍然想在字符串中间“插入”一些东西,所以对我来说,我喜欢snprintf()解决方案的结局。谢谢你的回答!我很久以前就放弃了这项工作:-(.无论如何,我不确定这两个函数之间有多大区别。复制或打印,我仍然想在字符串的中间“插入”一些东西,所以对我来说,我喜欢snprintf()解决方案的结局。