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

有效地确定字符数组大小以使用 snprintf()

晁璞
2023-03-14

我们在大学里有一个小作业,要求我们在c语言中执行一些X任务。这个问题的一部分是将一个无符号的长整型数转换成一个字符串,这个长整型数是在程序运行过程中产生的,因此无法预先定义它。很自然,我使用了< code>snprintf。我初始化了一个很大的数组(str[50]),以避免任何类型的缓冲区错误。

然而,在提交时,我的教授说我避免缓冲区错误的方法无效。

我现在的问题是,当我创建一个char数组来保存无符号的长整型值时,我把它做成什么大小?是否有一些 C 宏来帮助确定无符号长整型可以容纳的最大字符数?

可能是这样的,

char str[MAX_NUMBER_OF_DIGITS_OF_UNSIGNED_LONG_ON_MACHINE];

我浏览了一些博客和这个论坛,但没有达成一致。任何帮助都将不胜感激!

共有3个答案

公孙威
2023-03-14

snprintf的文档中:

关于snprintf()的返回值,SUSv2和C99相互矛盾:当snprintf()以size=0调用时,SUSv2规定了一个小于1的未指定返回值,而C99在这种情况下允许str为NULL,并给出返回值(一如既往)作为在输出字符串足够大的情况下会写入的字符数。

如果您使用的是C99,您可以使用snprintf来确定大小(正如BLUEPIXY所评论的):

int size = snprintf(NULL, 0, "%lu", ULONG_MAX);

但是,如果您不能使用 C99,则可以通过确定所需的位数并为终止 \0 字符添加一个附加字符来确定字符串大小:

int size = (int) log10((double) ULONG_MAX) + 1;

为了给数组分配< code>size字节,只需使用

char str[size];

但是,这仅在编译器/版本支持VLA时才有效,如果编译器不支持此功能,则可以动态分配数组

char *str = malloc(size);    //< Allocate the memory dynamically
// TODO: Use the str as you would the character array
free(str);                   //< Free the array when you are finished
曾云
2023-03-14
#if ULONG_MAX == 4294967295UL
#  define SIZE (10 + 1)
#elif ULONG_MAX <= 18446744073709551615ULL
#  define SIZE (20 + 1)
#endif
东郭翰音
2023-03-14

请选择@BLUEPIXY以简洁明了。

一个更深层次的答案。

C允许各种“区域设置”,因此,从理论上讲,snprintf(...,“%lu”,...)可以打印比预期更长的字符串。输出可以是“1,234,567”,而不是“1234567”。

推荐:
1.确定最大整数的大小,n
2.n*log2(10)四舍五入1以获取char计数。
3.设置一个最大需要2x的缓冲区。
4.检查snprintf结果。
5.利基问题:使用带有snprintf()的双重调用需要确保“语言环境”和号码在调用之间不会改变-不要在这里使用,因为snprintf()是一个功能昂贵的调用。

char *ulong_to_buf(char *buf, size_t size, unsigned long x) {
    int n = snprintf(buf, size, "%lu", x);
    if (n < 0 || n >= size) return NULL;
    return buf;
}

// Usage example
void foo(unsigned long x)
  // 1/3 --> ~log2(10)
  #define ULONG_PRT_LEN (sizeof(unsigned long)*CHAR_BIT/3 + 2)
  char buf[ULONG_PRT_LEN*2 + 1];  // 2x for unexpected locales
  if (ulong_to_buf(, sizeof buf, x)) {
    puts(buf);
  }

如果真的关心代码,就自己写吧

#include <stdlib.h>
#include <limits.h>
#include <string.h>
#define PRT_ULONG_SIZE (sizeof(unsigned long) * CHAR_BIT * 10 / 33 + 3)

char *ulong_strnull(int x, char *dest, size_t dest_size) {
  char buf[PRT_ULONG_SIZE];
  char *p = &buf[sizeof buf - 1];
  // Form string
  *p = '\0';
  do {
    *--p = x % 10 + '0';
    x /= 10;
  } while (x);
  size_t src_size = &buf[sizeof buf] - p;
  if (src_size > dest_size) {
    // Not enough room
    return NULL;
  }
  return memcpy(dest, p, src_size); // Copy string
}
 类似资料:
  • 问题内容: 我来自php背景,在php中,有一个函数可以告诉您数组中使用了多少个元素。 数组有类似的方法吗?谢谢。 问题答案: 是的(类属性,而不是方法):

  • 我不知道这是怎么运作的。所以任何人都可以帮我。

  • 我有一个随机地址字符串,如 我想将其拆分为具有两个条件的字符串数组: 该字符串数组的每个元素的长度小于或等于20 字符串数组的元素没有尴尬的结尾 例如,每20个字符拆分将产生: 但正确的输出是: 注意字符串数组中的每个元素是如何小于或等于20的。 以上是我对这段代码的输出:

  • 问题内容: 在谷歌搜索时,我发现使用会很慢。 也有可用的方法。 Java中是否有一种有效的方法来获取文件大小? 问题答案: 好吧,我尝试使用下面的代码对其进行度量: 对于运行次数= 1和迭代次数= 1,URL方法大多数时候是最快的,其次是频道。我以大约十次的新鲜暂停运行。因此对于一次访问,使用URL是我想到的最快方法: 如果运行次数= 5,迭代次数= 50,则绘制的图片会有所不同。 文件必须缓存对

  • 本文向大家介绍Java程序以给定大小的组反转数组,包括了Java程序以给定大小的组反转数组的使用技巧和注意事项,需要的朋友参考一下 通过反转所需大小的子数组,可以按给定大小的组反转数组。一个例子如下。 演示此过程的程序如下。 示例 输出结果 现在让我们了解上面的程序。 首先打印原始数组。然后,使用for循环将给定大小(即4)的组反转为数组。演示此操作的代码段如下所示。 然后显示修改后的数组。演示此

  • 有人能给我解释一下上面这一行的记忆地图吗。它将有多少个对象和引用?