Untitled

 avatar
unknown
plain_text
2 months ago
3.6 kB
1
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <stdint.h>

#define our_type unsigned short int

// Макросы для определения характеристик типа
#define IS_SIGNED(type) ((type)-1 < (type)0)
#define GET_MAX_VALUE(type) _Generic((type), \
    signed char: SCHAR_MAX,                \
    unsigned char: UCHAR_MAX,              \
    signed short: SHRT_MAX,                \
    unsigned short: USHRT_MAX,             \
    signed int: INT_MAX,                   \
    unsigned int: UINT_MAX,                \
    signed long: LONG_MAX,                 \
    unsigned long: ULONG_MAX,              \
    signed long long: LLONG_MAX,           \
    unsigned long long: ULLONG_MAX         \
)
#define GET_MIN_VALUE(type) _Generic((type), \
    signed char: SCHAR_MIN,                \
    signed short: SHRT_MIN,                \
    signed int: INT_MIN,                   \
    signed long: LONG_MIN,                 \
    signed long long: LLONG_MIN,           \
    default: (type)0                       \
)

our_type get_number() {
    char buffer[1024] = {0};
    int index = 0;
    int ch;
    const int is_signed = IS_SIGNED(our_type);
    const our_type max_val = GET_MAX_VALUE(our_type);
    const our_type min_val = GET_MIN_VALUE(our_type);

    while (1) {
        ch = getchar();

        if (ch == '\n') { // Enter
            if (index == 0 || (index == 1 && buffer[0] == '-')) {
                printf("\nInvalid input. Try again: ");
                fflush(stdout);
                index = 0;
                memset(buffer, 0, sizeof(buffer));
                continue;
            }
            break;
        }

        if (ch == '\b') { // Backspace
            if (index > 0) {
                index--;
                printf("\b \b");
                buffer[index] = '\0';
            }
            continue;
        }

        if (index == 0 && ch == '-') {
            if (is_signed) {
                buffer[index++] = ch;
                putchar(ch);
            }
            continue;
        }

        if (isdigit(ch)) {
            // Проверка на незначащие нули
            if (index == 0 && ch == '0') {
                buffer[index++] = ch;
                putchar(ch);
                continue;
            }
            if (index == 1 && buffer[0] == '-' && ch == '0') {
                continue; // "-0" недопустимо
            }

            // Проверка длины числа
            char temp[1024];
            strcpy(temp, buffer);
            temp[index] = ch;
            temp[index + 1] = '\0';

            // Проверка диапазона
            int valid = 1;
            if (is_signed) {
                int64_t num = strtoll(temp, NULL, 10);
                if (num > max_val || num < min_val) valid = 0;
            } else {
                uint64_t num = strtoull(temp, NULL, 10);
                if (num > max_val) valid = 0;
            }

            if (valid) {
                buffer[index++] = ch;
                putchar(ch);
            }
        }
    }

    // Преобразование результата
    return (our_type)(is_signed ? strtoll(buffer, NULL, 10) : strtoull(buffer, NULL, 10));
}

int main() {
    printf("Enter the number: ");
    fflush(stdout);
    our_type num = get_number();
    printf("\nResult: %hu\n", num);
    return 0;
}
Editor is loading...
Leave a Comment