Точка в форматированном вводе.

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Firotti
Сообщения: 1
Зарегистрирован: 16 апр 2017, 13:38

16 апр 2017, 13:56

Приветствую. Может кто сообразит.
Вот простой код на С.

Код: Выделить всё

#include <stdio.h>

int main(void) {

    int c;

    printf("Enter the number: ");
    scanf("%i", &c);
		
    return 0;
}
Как сделать так, чтобы при выполнении программы после введенного пользователем значения выводилась и точка?
Иными словами выводимая информация имела бы вид: Enter the number: 145.
вместо: Enter the number: 145
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

16 апр 2017, 22:48

Это не совсем тривиальная задача. Дело в том, что Enter, который нажимает пользователь после ввода значения, попадает в output (то есть в консоль) и только после этого обрабатывается функцией scanf. Таким образом, чтобы поставить точку в конце ввода, нам нужно будет вручную вернуть консольный курсор в конец предыдущей строки. Сложность в том, что подобная возможность предусмотрена далеко не на всех операционных системах, так что в стандартном С-шном Crt даже нет соответствующей функции. Если мы работаем под Windows (где произвольно менять положение курсора в консоли разрешено), то можно посмотреть в сторону Win API функции SetConsoleCursorPosition. Однако будет необходимо запомнить положение курсора до ввода, плюс учесть сколько символов было введено пользователем (на это указывает значение, которое вернула функция scanf). Дополнительная проблема может возникнуть в том случае, если строка приглашения являлась последней строкой на экране. В этом случае после ввода консоль будет проскролена вверх. Это тоже нужно учесть взяв текущее положение курсора после ввода и сравнив номер строки из положения до ввода.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Din666
Сообщения: 51
Зарегистрирован: 17 июл 2015, 13:25
Откуда: Moscow
Контактная информация:

19 апр 2017, 14:42

Вариант со своей ф-цией ввода (чистый си , никаких плюсов))
правда backspace не работает (

Код: Выделить всё

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#ifdef __linux__
#include <termios.h>

enum enEnableDisable{ ENABLE, DISABLE };

static void carriageReturn(enEnableDisable disable = DISABLE) {
    static const int flags = (ICANON | ECHO);
    struct termios t;
    tcgetattr(STDIN_FILENO, &t);
    if ( disable ) {
        t.c_lflag &= ~flags;
    } else {
        t.c_lflag |= flags;
    }
    tcsetattr(STDIN_FILENO, TCSANOW, &t);
}

static char getSymbol() {
    char c = 0;
    read(STDIN_FILENO, &c, 1);
    return c;
}

#else // WINDOWS
#include <conio.h>
inline static char getSymbol() {
    return getch();
}
#endif

int readInt(const int maxLen = 255) {

    char str[maxLen];
    int len = 0;
    bzero(str, sizeof(str));

#ifdef __linux__
    carriageReturn(DISABLE);
#endif

    while ( (sizeof(str)-1) > len && '\n' != ( str[len] = getSymbol()) ) {
        printf("%c", str[len]);
        fflush(stdout);
        ++len;
    }
    printf(".\n");
    fflush(stdout);

#ifdef __linux__
    carriageReturn(ENABLE);
#endif
    return atoi(str);
}

int main() {

    int c = 0;
    
    printf("Enter the number: ");
    fflush(stdout);

    c = readInt();

    return EXIT_SUCCESS
}
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

19 апр 2017, 15:25

Интересное решение. Читаем не с помощью scanf, а посимвольно, и сами выводим символы. Потом дорисовываем в конце точку и перевод каретки.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить