用C语言将字节数转换为文件大小
我想将单个字节数转换为文件大小(即.KB、.MB和.GB) 如果数字是0,我不想要任何单位。 如果这个数字可以被1024的倍数整除(不是浮点数),那么我将打印:x。否则,我想打印一个精度为1度的浮点 我做了一些代码,似乎工作得很好,但它非常麻烦。我正在寻找使我的功能更干净/更高效的方法,请注意,这真的很难看:用C语言将字节数转换为文件大小,c,size,C,Size,我想将单个字节数转换为文件大小(即.KB、.MB和.GB) 如果数字是0,我不想要任何单位。 如果这个数字可以被1024的倍数整除(不是浮点数),那么我将打印:x。否则,我想打印一个精度为1度的浮点 我做了一些代码,似乎工作得很好,但它非常麻烦。我正在寻找使我的功能更干净/更高效的方法,请注意,这真的很难看: char * calculateSize( off_t size ) { char *result = (char *) malloc(sizeof(char) * 20); st
char *
calculateSize( off_t size )
{
char *result = (char *) malloc(sizeof(char) * 20);
static int GB = 1024 * 1024 * 1024;
static int MB = 1024 * 1024;
static int KB = 1024;
if (size >= GB) {
if (size % GB == 0)
sprintf(result, "%d GB", size / GB);
else
sprintf(result, "%.1f GB", (float) size / GB);
}
else if (size >= MB) {
if (size % MB == 0)
sprintf(result, "%d MB", size / MB);
else
sprintf(result, "%.1f MB", (float) size / MB);
}
else {
if (size == 0) {
result[0] = '0';
result[1] = '\0';
}
else {
if (size % KB == 0)
sprintf(result, "%d KB", size / KB);
else
sprintf(result, "%.1f KB", (float) size / KB);
}
}
return result;
}
如果有人有更好的方法来达到同样的效果,我将不胜感激。我会使用表格法。大致如下:
void
printsize(size_t size)
{
static const char *SIZES[] = { "B", "kB", "MB", "GB" };
size_t div = 0;
size_t rem = 0;
while (size >= 1024 && div < (sizeof SIZES / sizeof *SIZES)) {
rem = (size % 1024);
div++;
size /= 1024;
}
printf("%.1f %s\n", (float)size + (float)rem / 1024.0, SIZES[div]);
}
void
打印尺寸(尺寸)
{
静态常量字符*大小[]={“B”、“kB”、“MB”、“GB”};
大小div=0;
尺寸=0;
而(大小>=1024&&div<(大小/大小){
rem=(大小%1024);
div++;
大小/=1024;
}
printf(“%.1f%s\n”,(浮点)大小+(浮点)rem/1024.0,大小[div]);
}
使用扩展到EiB的表驱动表示法
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DIM(x) (sizeof(x)/sizeof(*(x)))
static const char *sizes[] = { "EiB", "PiB", "TiB", "GiB", "MiB", "KiB", "B" };
static const uint64_t exbibytes = 1024ULL * 1024ULL * 1024ULL *
1024ULL * 1024ULL * 1024ULL;
char *
calculateSize(uint64_t size)
{
char *result = (char *) malloc(sizeof(char) * 20);
uint64_t multiplier = exbibytes;
int i;
for (i = 0; i < DIM(sizes); i++, multiplier /= 1024)
{
if (size < multiplier)
continue;
if (size % multiplier == 0)
sprintf(result, "%" PRIu64 " %s", size / multiplier, sizes[i]);
else
sprintf(result, "%.1f %s", (float) size / multiplier, sizes[i]);
return result;
}
strcpy(result, "0");
return result;
}
由于您对GB、MB和KB使用相同的逻辑,因此最好将该逻辑移到单独的函数中。您可能希望使用long而不是int。感谢这些改进!严格地说,您的格式不符合要求,但很容易修复。非常感谢!我喜欢你的解决方案!谢谢次要的挑剔:如果数字为2047,则结果字符串为“2.0 KiB”。在这里,我期望“1.9千磅”。这是一个很好的代码,谢谢。@neoneye:准确地说,1997年和2099年之间的所有值(2048年除外)都报告为2.0 KiB。类似地,1025到1075之间的值报告为1.0 KiB,但973到1023之间的值报告为这些整数值。基本上,这是一个四舍五入的问题。如果希望截断而不是取整,则相应地修改计算。将
(float)size/multiplier
替换为更复杂的内容,如floor((10.0*size)/multiplier)/10.0
。我们可以讨论在演员阵容中使用float
vsdouble
——这是从问题中遗留下来的。
int main(void)
{
uint64_t list[] =
{
0, 1, 2, 34, 900, 1023, 1024, 1025, 2048, 1024 * 1024,
1024 * 1024 * 1024 + 1024 * 1024 * 400
};
int i;
for (i = 0; i < DIM(list); i++)
{
char *str = calculateSize(list[i]);
printf("%18" PRIu64 " = %s\n", list[i], str);
free(str);
}
return 0;
}
0 = 0
1 = 1 B
2 = 2 B
34 = 34 B
900 = 900 B
1023 = 1023 B
1024 = 1 KiB
1025 = 1.0 KiB
2048 = 2 KiB
1048576 = 1 MiB
1493172224 = 1.4 GiB