A ver, lástima que no haya nada como %m en windows pero se puede simular. La idea es ir adquiriendo trozos razonables de memoria con realloc, para no ir perdiendo tiempo en adquisición de memoria y copia.
En este caso se adquieren bloques de memoria de 10 bytes cada vez. Cuando se llena se adquieren 10 más de forma automática. Para el final de la adquisición de la cadena, marcado por el carácter '\n', de añade el carácter nulo '\0' para marcar el final de la cadena si hay espacio; si no añade un byte más exproceso para alojarlo.
Al final se genera una cadena dinámica del mismo tamaño que la adquirida por teclado y se le copiará el contenido. La cadena auxiliar, la utilizada para adquirir del teclado es destruida y se devuelve la cadena ajustada. Eso sí, hay que recordar destruirla cuando ya no se necesite. Se considera que un char es un byte.
				
			En este caso se adquieren bloques de memoria de 10 bytes cada vez. Cuando se llena se adquieren 10 más de forma automática. Para el final de la adquisición de la cadena, marcado por el carácter '\n', de añade el carácter nulo '\0' para marcar el final de la cadena si hay espacio; si no añade un byte más exproceso para alojarlo.
Al final se genera una cadena dinámica del mismo tamaño que la adquirida por teclado y se le copiará el contenido. La cadena auxiliar, la utilizada para adquirir del teclado es destruida y se devuelve la cadena ajustada. Eso sí, hay que recordar destruirla cuando ya no se necesite. Se considera que un char es un byte.
Código (c) [Seleccionar] 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* string_input() {
    char *ret_val; // cadena que será devuelta
    char *str = NULL; // cadena auxiliar para conseguir datos del teclado
    char c;
    const unsigned chunk = 10; // tamaño de trozos de memoria en bytes o caracteres
    int i=0; // posición del cursor en str
    while((c=getchar())!='\n') { // adquisición por teclado
        if(i%chunk == 0) // si i ha alcanzado el máximo de memoria
            str=realloc(str, i+chunk); // añadirle más 
        str[i] = c; // copiar el caracter adquirido a la cadena
        ++i; // avanzar el puntero en str
    }
    if(i%chunk == 0) // si i ha alcanzado el máximo de memoria
        str=realloc(str, i+1); // añadir un byte más a str
    str[i] = '\0'; // cerrar la cadena
    ret_val = malloc(strlen(str)+1); // dimensionar la cadena de regreso con el tamaño exacto
    strcpy(ret_val, str); // copiar la cadena
    free(str); // borrar la cadena auxiliar
    return ret_val; // devolver la cadena resultado
}
int main(void) {
    char *str;
    printf("> ");
    str = string_input();
    printf("%s", str);
    free(str);
}