#include <stdio.h> #define SECTOR_SIZE_DEFAULT 512LL #define KILOBYTE_SIZE 1000LL #define MEGABYTE_SIZE 1000000LL #define GIGABYTE_SIZE 1000000000LL #define TERABYTE_SIZE 1000000000000LL #define KIBIBYTE_SIZE 1024LL #define MEBIBYTE_SIZE 1048576LL #define GIBIBYTE_SIZE 1073741824LL #define TEBIBYTE_SIZE 1099511627776LL typedef enum { DIGIT_UNIT_BYTE, DIGIT_UNIT_KILOBYTE, DIGIT_UNIT_MEGABYTE, DIGIT_UNIT_GIGABYTE, DIGIT_UNIT_TERABYTE, DIGIT_UNIT_KIBIBYTE, DIGIT_UNIT_MEBIBYTE, DIGIT_UNIT_GIBIBYTE, DIGIT_UNIT_TEBIBYTE } DigitUnit; /* Inefficiently removes all spaces from a string, in-place. */ static void strip_string (char* str) { int i; for (i = 0; str[i] != 0; i++) { if (isspace (str[i])) { int j; for (j = i + 1; str[j] != 0; j++) str[j - 1] = str[j]; } } } /* Find non-number suffix. Eg: find_suffix("32Mb") returns a pointer to * "Mb". */ static char* find_suffix (const char* str) { while (str[0] != 0 && (isdigit (str[0]) || strchr(",.-", str[0]))) str++; return (char *) str; } static DigitUnit parse_unit_suffix (const char* suffix) { if (strlen (suffix) > 1 && tolower (suffix[1]) == ‘i‘) { switch (tolower (suffix[0])) { case ‘k‘: return DIGIT_UNIT_KIBIBYTE; case ‘m‘: return DIGIT_UNIT_MEBIBYTE; case ‘g‘: return DIGIT_UNIT_GIBIBYTE; case ‘t‘: return DIGIT_UNIT_TEBIBYTE; } } else if (strlen (suffix) > 0) { switch (tolower (suffix[0])) { case ‘b‘: return DIGIT_UNIT_BYTE; case ‘k‘: return DIGIT_UNIT_KILOBYTE; case ‘m‘: return DIGIT_UNIT_MEGABYTE; case ‘g‘: return DIGIT_UNIT_GIGABYTE; case ‘t‘: return DIGIT_UNIT_TERABYTE; } } return -1; } long long unit_parse (const char *str) { char *suffix; long long byte = -1; long long byte_block = 1; strip_string (str); suffix = find_suffix (str); DigitUnit unit = parse_unit_suffix (suffix); switch (unit) { case DIGIT_UNIT_BYTE: break; case DIGIT_UNIT_KILOBYTE: byte_block = KILOBYTE_SIZE; break; case DIGIT_UNIT_MEGABYTE: byte_block = MEGABYTE_SIZE; break; case DIGIT_UNIT_GIGABYTE: byte_block = GIGABYTE_SIZE; break; case DIGIT_UNIT_TERABYTE: byte_block = TERABYTE_SIZE; break; case DIGIT_UNIT_KIBIBYTE: byte_block = KIBIBYTE_SIZE; break; case DIGIT_UNIT_MEBIBYTE: byte_block = MEBIBYTE_SIZE; break; case DIGIT_UNIT_GIBIBYTE: byte_block = GIBIBYTE_SIZE; break; case DIGIT_UNIT_TEBIBYTE: byte_block = TEBIBYTE_SIZE; break; } double temp = 0; if (sscanf (str, "%lf", &temp) == 1) byte = temp * byte_block; return byte; } int main(int argc, char **argv) { if (argc > 1) printf ("%lld\n", unit_parse (argv[1])); }
时间: 2024-11-10 08:30:27