Skip to content

Instantly share code, notes, and snippets.

@dgoguerra
Last active November 29, 2023 03:08
Show Gist options
  • Save dgoguerra/7194777 to your computer and use it in GitHub Desktop.
Save dgoguerra/7194777 to your computer and use it in GitHub Desktop.
Format a quantity in bytes into a human readable string (C)
#include <stdio.h>
#include <stdlib.h> // atoll
#include <stdint.h> // uint64_t
#include <inttypes.h> // PRIu64
static const char *humanSize(uint64_t bytes)
{
char *suffix[] = {"B", "KB", "MB", "GB", "TB"};
char length = sizeof(suffix) / sizeof(suffix[0]);
int i = 0;
double dblBytes = bytes;
if (bytes > 1024) {
for (i = 0; (bytes / 1024) > 0 && i<length-1; i++, bytes /= 1024)
dblBytes = bytes / 1024.0;
}
static char output[200];
sprintf(output, "%.02lf %s", dblBytes, suffix[i]);
return output;
}
int main(int argc, char **argv)
{
if (argc == 1) {
fprintf(stderr, "Usage: %s <bytes>\n", *argv);
return 1;
}
uint64_t bytes = atoll(argv[1]);
printf("%" PRIu64 " Bytes: %s\n", bytes, humanSize(bytes));
return 0;
}
@amr3k
Copy link

amr3k commented Jan 25, 2019

Thanks for this example.
Wouldn't it be better if you allocated a char* variable and send its address to function to assign the result to it directly?

@chaoyangnz
Copy link

cool, when 1024 it prints "1024 B". maybe 1K would be good.
And the static buffer is error-prone,,,

@arataca89
Copy link

arataca89 commented Apr 8, 2022

Thanks for this code _ / \ _

@jjbailey
Copy link

Another variation:

char *humanSize(uint64_t bytes, char *hrbytes)
{
    char   *suffix[] = { "B", "KB", "MB", "GB", "TB" };
    char    length = sizeof(suffix) / sizeof(suffix[0]);
    int     i;

    for(i = 0; i < length; i++) {
        if(bytes < 1024)
            break;

        bytes >>= 10;
    }

    snprintf(hrbytes, BUFSIZ, "%lu%s", bytes, suffix[i]);
    return(hrbytes);
}

@ihsan6133
Copy link

How does this work? how can you return a pointer to a stack array, wouldnt the pointer point to garbage??

@jjbailey
Copy link

I'm sorry, I should have explained this more. I prefer not to return pointers to static data. Here's an example of usage:

int main(int argc, char **argv)
{
    char   *humanSize(uint64_t, char *);
    char    hrbytes[BUFSIZ];

    printf("bytes = %s\n", humanSize(12345, hrbytes));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment