C 有效确定字符数组大小以使用snprintf()
我们有一个来自大学的小作业,要求我们在C。 该问题的一部分是将程序过程中生成的无符号长数字(因此没有任何方法对其进行预测试)转换为字符串。当然,我使用了C 有效确定字符数组大小以使用snprintf(),c,C,我们有一个来自大学的小作业,要求我们在C。 该问题的一部分是将程序过程中生成的无符号长数字(因此没有任何方法对其进行预测试)转换为字符串。当然,我使用了snprintf。我初始化了一个数组(str[50]),该数组的大小非常大,可以避免任何类型的缓冲区错误 然而,在提交时,我的教授说我避免缓冲区错误的方法是无效的 我现在的问题是,当我创建一个char数组来保存无符号的long值时,它的大小是多少?是否有一些C宏可以帮助确定无符号长字符可以容纳的最大字符数 可能是 char str[MAX_NUM
snprintf
。我初始化了一个数组(str[50]),该数组的大小非常大,可以避免任何类型的缓冲区错误
然而,在提交时,我的教授说我避免缓冲区错误的方法是无效的
我现在的问题是,当我创建一个char数组来保存无符号的long值时,它的大小是多少?是否有一些C宏可以帮助确定无符号长字符可以容纳的最大字符数
可能是
char str[MAX_NUMBER_OF_DIGITS_OF_UNSIGNED_LONG_ON_MACHINE];
我浏览了limits.h和一些博客以及这个论坛,但没有达成一致。任何帮助都将不胜感激 来自
snprintf
的文档:
关于snprintf()、SUSv2和C99的返回值
反驳
彼此:当使用size=0调用snprintf()时,SUSv2
未指定的返回值小于1,而C99允许使用str
在本例中为NULL,并将返回值(一如既往)作为数字
输出字符串的大小写中本应写入的字符数
已经足够大了
如果您使用的是C99,则可以使用snprintf确定大小(如BLUEPIXY所述):
但是,如果不能使用C99,则可以通过确定所需的位数并为终止的\0
字符添加额外字符来确定字符串大小:
int size = (int) log10((double) ULONG_MAX) + 1;
为了给数组分配大小
字节,您只需使用
char str[size];
但是,这仅在编译器/版本支持的情况下有效,如果编译器不支持,则可以使用
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
char*str=malloc(大小);//<动态分配内存
//TODO:像使用字符数组一样使用str
自由(str);//<完成后释放阵列
#如果ULONG_MAX==4294967295UL
#定义大小(10+1)
#elif ULONG_MAX为简洁起见,请使用
更深层次的回答
C允许各种“区域设置”,因此理论上,snprintf(…,%lu,…)
可以打印比预期更长的字符串。输出可以是“1234567”,而不是“1234567”
推荐:
1.确定最大整数的大小(位)n
。
2. <代码>n*log2(10)
向上取整+1,得到字符数。char
count。3.设置一个最大需要2倍的缓冲区。
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);
}
char*ulong\u to\u buf(char*buf,size\t size,无符号长x){
int n=snprintf(buf,大小,“%lu”,x);
如果(n<0 | | n>=size)返回NULL;
返回buf;
}
//用法示例
void foo(无符号长x)
//1/3-->~log2(10)
#定义ULONG_PRT_LEN(sizeof(无符号长)*字符位/3+2)
字符buf[ULONG_PRT_LEN*2+1];//意外地区的2倍
if(ulong_至_buf(,尺寸buf,x)){
put(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
}
#包括
#包括
#包括
#定义PRT_ULONG_大小(sizeof(无符号长)*字符位*10/33+3)
char*ulong\u strnull(整数x,char*dest,size\u t dest\u size){
char buf[PRT_ULONG_SIZE];
char*p=&buf[sizeof buf-1];
//表单字符串
*p='\0';
做{
*--p=x%10+‘0’;
x/=10;
}而(x),;
大小src大小=&buf[sizeof buf]-p;
如果(src\U尺寸>目的地尺寸){
//空间不够
返回NULL;
}
返回memcpy(dest,p,src_size);//复制字符串
}
1)int size=snprintf(NULL,0,“%lu”,ULONG_MAX)代码>2)int size=(int)log10((double)ULONG_MAX)+1
then+1表示NUL。虽然这给了我一个很好的估计,它能容纳多少位数字,但我不能用这个信息在c中创建一个如此大小的数组!您是否将数字从无符号长
转换为十进制或十六进制的字符串
?因为在十六进制的情况下,你可能会使用一些通用的东西,比如为STR(sizeof(你使用的类型)*2+1)
你不能在宏条件下使用1不能使用sizeof
。\elif
行替换为\else
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
}