当前位置: 首页 > 知识库问答 >
问题:

MinGW的msvcrt替代方案?(例如,获得合格的snprintf)

哈烨熠
2023-03-14

所以这里有一个有趣的。。。

我们有一些C库应该独立于平台,即使它们是在linux上开发的,因为它们只依赖于ISO/IEC 9899:1999中定义的c标准库。当我们用MinGW编译这些库时,起初一切似乎都很正常,但是今天我们发现msvcrt的snprintf()实现是brainda...抱歉,我的意思是“不兼容”C99标准中的定义。

我希望MinGW会发出警告,告诉我-std=c99实际上并不完全受支持。否则我怎么知道呢?

是否有任何替代的c标准库窗口,最重要的是:可以告诉MinGW以某种方式链接到它,而不是msvcrt?

如果没有,我们至少需要一个列表或其他东西来检查关于msvcrt和c99的其他潜在可移植性问题。

附言:我知道Cygwin和MSYS2,但我更喜欢原生窗口二进制文件(部分原因是我们也在Matlab中使用我们的库)。

编辑:对不起,我应该更清楚地解释一下我的msvcrt的snprintf()的问题到底是什么。根据该标准,如果输出不合适,则需要snprintf()输出'\0'作为最后一个字符。但是,msvcrt不这样做,因此结果字符串不再正确终止。我不知道为什么会有人选择用这种方式实现snprintf(),因为对我来说,省略“\0”一点意义都没有。

我们还尝试了建议的uu USE u MINGW ANSI STDIO,但我想这只是修复了缺少的格式说明符?至少它似乎对我们的具体问题没有影响。

共有2个答案

戚繁
2023-03-14

如果您需要MinGW-w64中的C99 stdio,您可以定义\u使用\u MinGW\u ANSI\u stdio,以便绕过msvcrt实现。最好通过编译器参数来定义它

-D__USE_MINGW_ANSI_STDIO

或者,您可以尝试使用MinGW-w64构建,该构建是为了与新的ucrt链接而设置的,但我不知道有任何预先存在的易于使用的稳定构建是以这种方式设置的。

姬博瀚
2023-03-14

该标准强制执行snprintf的行为如下:

否则,n-1st以外的输出字符将被丢弃,而不是写入数组,并且在实际写入数组的字符末尾写入空字符。

msvcrt中的snprintf确实不是标准版本,但是这里解释的是Microsoft版本:
snprintf()总是以null结尾吗?

以下代码给出不兼容的结果:

#include <stdio.h>

int main (void)
{
  char dst[3];
  snprintf(dst, 3, "%c%c%c", 'A', 'B', 'C');

  for(size_t i=0; i<3; i++)
  {
    printf("%.2X ", dst[i]);
  }
}

我得到了不符合标准的输出414243。要获得标准C,您必须在stdio之前添加它。h包括:

#define __USE_MINGW_ANSI_STDIO 1

现在你得到的41 42 00是兼容的。

所有这些程序安全问题的根源是微软,在过去20年中,微软一直在其产品中使用不合规的C库。

 类似资料:
  • 问题内容: 除了看起来不太好以外,是否有其他替代方法可以在Java中实现切换案例。根据选择必须执行的方法,一组值会组合在一起。 问题答案: 想必您正在努力满足案件不变的要求。通常,这是代码气味,但是您可以做一些事情。您可能想提出并链接到另一个详细说明您为何尝试切换的问题。 在上面的示例中,您可能想要映射到“处理程序”,例如 然后,这一切都变成了查找。 同样,这有点气味,因此请发布一个说明原因的问题

  • 我正在开发一个有ContentManager类的应用程序。该类从包中迁移文件,并在首次打开应用程序时执行其他检查。接下来,在一个相当长的ViewController链末端的view controller中使用它。据我所知,有两种实现方法: > 在第一个ViewController中实例化类,并将其通过segue传递到最终的ViewController。 在第一个ViewController中创建一

  • 问题内容: 出于各种原因,在编写 Java应用程序时 ,调用会被皱眉,所以如何通知调用过程并非一切都按计划进行? 编辑: 1是任何非零退出代码的。 问题答案: 当“应用程序”实际上是较大的Java应用程序(服务器)的子应用程序(例如servlet,applet)时,对的使用会被拒绝:在这种情况下,它可能会停止JVM并因此停止所有其他子应用程序。在这种情况下,抛出适当的异常(最好由应用程序框架/服务

  • 问题内容: 我知道这个话题已经解决了上千次。但是我找不到解决办法。 我正在尝试计算列表(df2.list2)的列中出现列表(df1.list1的每一行)的频率。所有列表仅包含唯一值。List1包含约300.000行,list2包含30.000行。 我有一个有效的代码,但是它的运行速度非常慢(因为我使用的是迭代程序)。我也尝试过itertuples(),但它给了我一个错误(“要解压缩的值太多(预期2

  • 允许我填充包含复选框和单选按钮的HTML表单的替代方法。 我已经设法使用eclipse中的HtmlUnit库将数据发送到html表单并检索页面(我已经发布了下面的Java代码)。 然而,当我将这些代码复制到我的Android项目中时,我发现Android不支持HtmlUnit库。 对于Android来说,HtmlUnit还有其他替代方案吗?另一种方法应该能够将文本、复选框、单选按钮填写到Html表

  • 问题内容: 我过去曾使用ServiceWrapper几次,但是,对于商业产品,双重许可有些复杂(通常需要付费)。是否存在具有类似功能的完全FOSS替代产品? 问题答案: 尽管我尚未完成评估,但YAJSW似乎是最好的选择。