I have implemented a C library to perform basic input operations on built-in data types with various error checks of more complexity. Any improvements or suggestions are appreciated.
smartinput.h
/*
 * This library 'smartinput' is written in c programming.
 * by @venudayyam (binary_10)
 *  
 * The library contains subroutines which perform basic input
 * operations on a built-in data types and provide robust
 * error checking.
 * 
 * It is recommend not to mix the stadard input functions with these
 * library functions when performing operations on standard input stream
 * 
 * routines are meant to be used only when input stream is connected to keyboard.
 * routines expect valid arguments to be passed (if any).
 * 
 * 
 * 
 * 
 *  PROS:
 * 
 * - data overflow and underflow check on input
 * 
 * - input buffer is flushed(empty) after each operation.
 * 
 * - input value is said to be valid only when
 *   it can be stored in the specified variable (data type) `as it is`.
 *   otherwise it is invalid.
 * 
 */
#ifndef SMARTINPUT_H
#define SMARTINPUT_H
#include <stdbool.h>
bool get_char(char *ch);
char* get_line(char *_s, int _len);
/* trailing white spaces are preserved */
char* get_string(char *_s, int _len);  
bool get_short(short *value);
bool get_ushort(unsigned short *value);
bool get_int(int *value);
bool get_uint(unsigned int *value);
bool get_long(long *value);
bool get_ulong(unsigned long *value);
bool get_ullong(unsigned long long *value);
bool get_llong(long long *value);
bool get_float(float *value);
bool get_double(double *value);
bool get_ldouble(long double *value);
#endif
smartinput.c
/*
 * This library 'smartinput' is written in c programming.
 * by @venudayyam (binary_10)
 *  
 * The library contains subroutines to perform basic input
 * operations on a built-in data types and provide robust
 * error checking.
 * 
 * It is recommend not to mix the stadard input functions with these
 * library functions when performing operations on standard input stream
 * 
 * routines are meant to be used only when input stream is connected to keyboard.
 * routines expect valid arguments to be passed (if any).
 * 
 * 
 * 
 * 
 *  PROS:
 * 
 * - data overflow and underflow check on input
 * 
 * - input buffer is flushed(empty) after each operation.
 * 
 * - input value is said to be valid only when
 *   it can be stored in the specified variable (data type) `as it is`.
 *   otherwise it is invalid.
 * 
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include "smartinput.h"
#define BUF_SIZE (1024)
static char buffer[BUF_SIZE];
char* get_line(char *_s, int _len)
{
    int ch;
    size_t i = 0;
    scanf(" ");
    while ((ch=getc(stdin)) != EOF && ch != '\n')
    {
        if (i < _len-1)
            _s[i++] = ch;
    }
    _s[i] = '\0';
    return _s;
}
char* get_string(char *_s, int _len)
{
    int ch;
    size_t i = 0;
    while ((ch=getc(stdin)) != EOF && ch != '\n')
    {
        if (i < _len-1)
            _s[i++] = ch;
    }
    _s[i] = '\0';
    return _s;
}
bool get_char(char *value)
{
    fgets(buffer,3,stdin);
    *value = buffer[0];
    if ((buffer[1] == '\0' && buffer[0] == '\n') ||
        (buffer[2] == '\0' && buffer[1] == '\n'))
    {
         return true;
    }
    else
    {
        if (buffer[0] != '\0')
        {
            scanf("%*[^\n]");
            getchar();
        }
        return false;
    }
}
bool get_short(short *value)
{
    char *temp;
    long v;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    v = strtol(buffer,&temp,10);
    *value = v;
    if (errno == ERANGE || v > SHRT_MAX || v < SHRT_MIN 
                                        || *temp != '\0')
        return false;
    else
        return true;
}
bool get_ushort(unsigned short *value)
{
    char *temp;
    unsigned long v;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    v = strtoul(buffer,&temp,10);
    *value = v;
    if (errno == ERANGE || v > USHRT_MAX || *temp != '\0')
        return false;
    else
        return true;
}
bool get_int(int *value)
{
    char *temp;
    long v;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    v = strtol(buffer,&temp,10);
    *value = v;
    if (errno == ERANGE || v > INT_MAX || v < INT_MIN 
                                       || *temp != '\0')
        return false;
    else
        return true;
}
bool get_uint(unsigned int *value)
{
    char *temp;
    unsigned long v;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    v = strtoul(buffer,&temp,10);
    *value = v;
    if (errno == ERANGE || v > UINT_MAX || *temp != '\0')
        return false;
    else
        return true;
}
bool get_long(long *value)
{
    char *temp;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    *value = strtol(buffer,&temp,10);
    if (errno == ERANGE || *temp != '\0')
        return false;
    else
        return true;
}
bool get_ulong(unsigned long *value)
{
    char *temp;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    *value = strtoul(buffer,&temp,10);
    if (errno == ERANGE || *temp != '\0')
        return false;
    else
        return true;
}
bool get_llong(long long *value)
{
    char *temp;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    *value = strtoll(buffer,&temp,10);
    if (errno == ERANGE || *temp != '\0')
        return false;
    else
        return true;
}
bool get_ullong(unsigned long long *value)
{
    char *temp;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    *value = strtoull(buffer,&temp,10);
    if (errno == ERANGE || *temp != '\0')
        return false;
    else
        return true;
}
bool get_float(float *value)
{
    char *temp;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    *value = strtof(buffer,&temp);
    if (errno == ERANGE || *temp != '\0')
        return false;
    else
        return true;
}
bool get_double(double *value)
{
    char *temp;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    *value = strtod(buffer,&temp);
    if (errno == ERANGE || *temp != '\0')
        return false;
    else
        return true;
}
bool get_ldouble(long double *value)
{
    char *temp;
    get_line(buffer, BUF_SIZE);
    errno = 0;
    *value = strtold(buffer,&temp);
    if (errno == ERANGE || *temp != '\0')
        return false;
    else
        return true;
}
sample.c
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "smartinput.h"
#define MAX_NAME 256
typedef struct _record
{
    char name[MAX_NAME];
    size_t id;
    char section;
}record;
void get_record(record *r)
{
    printf("name    : ");
    while (!get_line(r->name,MAX_NAME))
        fprintf(stderr,"error: invalid name. try again..\n");
    printf("section : ");
    while (!(get_char(&r->section) && r->section >= 'A'
                                   && r->section <= 'E'))
        fprintf(stderr,"error: invalid section. (select 'A'-'E'). try again..\n");
    printf("id      : ");
    while (!get_ulong(&r->id))
        fprintf(stderr,"error: invalid id. try again..\n");    
}
int main(void)
{
    record r;
    get_record(&r);
    printf("name : %s\nsec  : %c\nid  : %lu",r.name,r.section,r.id);
}
.
/* sample inputs and outputs of `get_int()` (note. sizeof(int) = 4) */
"2147483647\n"    -- true  (INT_MAX)
"2147483648\n"    -- false 
"-2147483648\n"   -- true  (INT_MIN)
"-2147483649\n"   -- false
"25ds\n"          -- false
"asdjkljasdf\n"   -- false 
"25 256\n"        -- false
"+1\n"            -- true
"-1\n"            -- true
EOF               -- false
" 1\n"            -- true


"123\n"," 123\n","123 x\n","\n123\n". \$\endgroup\$