【问题标题】:Customizable implementation of sprintf()sprintf() 的可定制实现
【发布时间】:2009-03-04 13:26:12
【问题描述】:

谁能指出我可以根据自己的需要自定义的源代码文件或包?

我为什么需要它的解释:字符串在我的代码中不是以空结尾的(二进制兼容)。因此 sprintf("%s") 是无用的,除非我修复代码以了解如何呈现字符串。

感谢 quinmars 指出可以通过 %s 打印字符串而不会以 null 终止。虽然它现在解决了需求,但我最终将需要 sprintf(或 snprintf)实现来实现使用变体的更高级别的功能。在到目前为止提到的其他内容中,在我看来 SQLite 实现是最好的。感谢 Doug Currie 指出。

【问题讨论】:

  • 你能解释一下你想在 sprintf() 中修改什么吗?这对我来说是一个危险信号,因为听起来有比复制复杂的 API 函数更好的解决方案。

标签: c printf


【解决方案1】:

我没有尝试过,因为我这里没有编译器,但是阅读手册页,看起来你可以为 '%s' 传递一个精度:

...如果给出精度,则没有空字符 需要在场;如果未指定精度或更大 比数组的大小,数组必须包含一个终止 NUL 字符。

那么你有没有尝试过这样做?

snprintf(buffer, sizeof(buffer), "%.*s", bstring_len, bstring);

如前所述,我没有对其进行测试,如果它有效,那么它当然只有在字符串中没有 '\0'-byte 时才有效。

编辑:我现在已经测试过了,它可以工作了!

【讨论】:

  • 正是我所看到的。
【解决方案2】:

您真的应该寻找 snprintf(sprintf 尊重输出缓冲区大小);谷歌建议http://www.ijs.si/software/snprintf/

【讨论】:

    【解决方案3】:

    作为 SQLite here 的一部分,有一个不错的公共域实现。

    我同意 Dickon Reed 的观点,即您需要 snprintf,它包含在 SQLite 版本中。

    【讨论】:

      【解决方案4】:

      我使用了this 伙计们的源代码。 它体积小、易于理解且易于修改(相对于 glib 和 libc)。

      【讨论】:

        【解决方案5】:

        根据此链接-http://www.programmingforums.org/thread12049.html

        如果你有完整的 gcc 发行版, C 库的源代码(glib 或 libc) 是子目录之一 这是为了搭便车。

        所以你可以在那里查看。 我不知道这会有多大帮助......

        【讨论】:

          【解决方案6】:

          我想修改 sprintf 的唯一原因是扩展它,而扩展它的唯一原因是当您正在编写某种解析器时。

          如果您希望为编码语言、XML 或任何具有语法的东西创建解析器,我建议您研究 Lexers 和 Parser Generators(最常用的两个是 Flex 和 @ 987654322@),它几乎可以为您编写极其复​​杂的解析器代码(尽管工具本身有些复杂)。

          否则,您可以在 Visual Studio 随附的源文件中找到它的代码(至少 2005 年和 2008 年,其他人可能有,但那两个肯定有)。

          【讨论】:

            【解决方案7】:

            glibc 中的 snprintf 可通过钩子/处理程序机制进行自定义

            【讨论】:

              【解决方案8】:

              只是一个想法... 示例:

              #include <stdio.h>
              #include <string.h>
              #include <stdarg.h>
              
              int sprintf(char * str, const char * format, ... )    
              {// Here you can redfine your input before continuing to compy with standard inputs
                  va_list args;
                  va_start(args, format);
                  vsprintf(str,format, args);// This still uses standaes formating
                  va_end(args);
                  return 0;// Before return you can redefine it back if you want...
              }
              int main (void)
              {
                  char h[20];
                  sprintf(h,"hei %d ",10);
                  printf("t %s\n",h);
                  getchar();
                  return 0;
              }
              

              【讨论】:

                【解决方案9】:

                看看汉森的C Interfaces: Implementations and Techniques。这是一本有趣的书,因为它是使用 Knuth 的 Literate Programming 技术编写的,并且它特别包含了一个基于 snprintf() 的可扩展格式化 I/O 接口。

                【讨论】:

                • 这是一本好书,但它在后台使用sprintf 来完成繁重的工作
                【解决方案10】:

                Marco Paland 设计了一个小型实现,我在this repository 中几乎解决了一些问题。完整的 C99 sprintf/vsprintf/etc 大约需要 720 行代码。与 sqlite 的 3993 相比(虽然 SQLite 可以使用更少;它包含这个 sqliteint.h 标头和很多不相关的东西。)

                【讨论】:

                  猜你喜欢
                  • 2013-05-14
                  • 2020-09-09
                  • 2015-04-10
                  • 2020-09-09
                  • 2011-03-23
                  • 2021-12-08
                  • 2013-02-13
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多