代码之家  ›  专栏  ›  技术社区  ›  con

如何sprintf编写一个没有限制警告的字符串?

c
  •  0
  • con  · 技术社区  · 5 年前

    我一直在使用这个代码:

    char options_string[96];
    sprintf(options_string,"%s_G%u", options_string, options.allowed_nucleotide_gap_between_CpN);
    

    但是我刚开始使用的GCC的新版本9警告我:

    警告:传递参数1以限制限定参数别名
    sprintf(options\u string,“%s\u G%u”,options\u string, 选项。允许的核苷酸之间的间隙);

    我读过这样的字符串最好的方法是使用sprintf,正如我所说: How to convert an int to string in C?

    我重新检查了密码,我没有使用任何代码 restrict 关键词。

    我如何才能在没有警告的情况下写入此字符串?

    0 回复  |  直到 5 年前
        1
  •  2
  •   supercat    5 年前

    一致的实施 sprintf 可以从向目标写入一个零字节开始,然后用输出的第一个字节(如果有的话)替换该字节,然后再写一个零,然后用输出的下一个字节替换第二个零字节,再写第三个零,这样的方法可以避免在处理最后一个字节之后执行任何特定的操作(例如写入终止零)。但是,尝试在这种实现中使用您的代码将失败,因为 options_string 在代码读取之前就被清除了。

        2
  •  3
  •   M.M    5 年前

    代码导致未定义的行为,因为字符缓冲区的同一部分同时用作的输入和输出 sprintf . 在这种情况下,警告是有用的信息。为了正确,您必须更改代码,以便输入和输出之间没有重叠。

    可能代码:

    char options_string[96];
    // ...assume you omitted some code that writes some valid string
    
    size_t upto = strlen(options_string);
    int written = snprintf(options_string + upto, sizeof options_string - upto,
        "_G%u", options.allowed_nucleotide_gap_between_CpN);
    if ( written < 0 || written + upto >= sizeof options_string )
    {
         // ...what you want to do if the options don't fit in the buffer
    }
    
        3
  •  0
  •   Yuri Ruzzene Barrozo    5 年前

    在您的例子中,最好使用strcat函数而不是sprintf,因为您希望连接一个字符串。