1. Си / Говнокод #25899

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    #include <ncurses.h>
    
    #if defined(_WIN32) || defined(_WIN64) 
        #include <windows.h>
        #define msleep(msec) Sleep(msec)
    #else
        #include <unistd.h>
        #define msleep(msec) usleep(msec*1000)
    #endif
    
    int main()
    {
        initscr();
    
        char str[100];
        addstr("Enter string: ");
        getstr(str); //Считваем строку
        curs_set(0); //"Убиваем" курсор, чтобы не мешался
        while ( true )
        {
        //Перемещаем х-координату как можно дальше вправо, и будем уменьшать её, пока она != 0
            for ( unsigned x = getmaxx(stdscr); x; x-- ) 
            {
                clear();
                mvaddstr(getmaxy(stdscr) / 2, x, str);
                refresh();
                msleep(200);
            }
        }
    
        endwin();
        return 0;
    }

    https://code-live.ru/post/ncurses-input-output/#getstr-
    Сколько хуйни вы можете найти в этом примере?

    Запостил: j123123, 04 Октября 2019

    Комментарии (96) RSS

    • >> Возможность комментировать эту статью отключена автором. Возможно, во всем виновата её провокационная тематика или большое обилие флейма от предыдущих комментаторов.
      Ответить
    • Хуйня первая:
      #include <ncurses.h>
      Должно быть:
      #include <ncurses/ncurses.h>
      Ответить
    • Первая хуйня в хуевом макросе
      #define msleep(msec) usleep(msec*1000)
      Если сделать usleep(2 + 2) то эта хуйня раскроется в usleep(2 + 2 * 1000) что явно не то, что надо. Да и вообще на кой хер делать функциеподобный макрос с маленькой буквы? Почему эту хуйню не сделать как функцию?

      Вторая хуйня в getstr() - эта хуйня настолько же небезопасна, как и gets().
      https://linux.die.net/man/3/getstr
      Вот что пишут про int getstr(char *str) :
      > The function getstr is equivalent to a series of calls to getch, until a newline or carriage return is received (the terminating character is not included in the returned string). The resulting value is placed in the area pointed to by the character pointer str.
      Т.е. если много хуйни написать, то можно переполнить буфер и попортить память. Чтоб такой хуйни не было, можно и нужно использовать int getnstr(char *str, int n)

      Еще одна н хуйня - а на кой хер собственно нужно после вечного цикла while(true) делать endwin(); ? Цикл никогда не завершится штатным способом, так что это нахрен не надо.

      Еще одна хуйня - в статье по ссылке написано "Но функцию задержки нам придётся придётся прописывать для каждой платформы отдельно, потому что unistd.h, как и windows.h это системозависимые библиотеки.". Это верно лишь отчасти. Некоторые компиляторы предоставляют необходимые обертки, например взгляните на это:
      https://github.com/Alexpux/mingw-w64/blob/d0d7f784833bbb0b2d279310ddc6afb52fe47a46/mingw-w64-crt/misc/mingw_usleep.c

      и хедер unistd.h там тоже есть
      https://github.com/Alexpux/mingw-w64/blob/d0d7f784833bbb0b2d279310ddc6afb52fe47a46/mingw-w64-headers/crt/unistd.h#L52

      так что таким компилятором оно нормально скомпилируется и на винде, и будет это вполне нативный виндовый бинарь
      Ответить
      • показать все, что скрытоvanished
        Ответить
        • MinGW — это не Cygwin. MinGW, если не использовать MSYS, генерирует бинарники, которые не требуют дополнительных библиотек (типа cygwin1.dll).

          Или обёрткой ты называешь любой код из сишных библиотек? Ну тогда и printf нельзя использовать, потому что это обёртка над WriteConsoleA.
          Ответить
          • показать все, что скрытоvanished
            Ответить
            • Да, в порте ncurses есть ссылка на переменные окружения TERMCAP и TERMINFO, но если их нет, то всё работает. И даже из каталога mingw никаких файлов не требуется.

              Похоже, что используется вшитое в библиотеку определение терминала, если TERMCAP и TERMINFO отсутствуют.
              Ответить
            • http://repo.msys2.org/mingw/sources/mingw-w64-i686-ncurses-6.0.20150627-2.src.tar.gz

              README.MinGW:
              This is work in progress, but it's in an state where one can see it
              works at least on the Windows Console.
              
              ...
              
              The TERM environment variable must be set specially to active the Windows
              console-driver.  The driver checks if TERM is set to "#win32con" (explicit
              use) or if TERM is unset or empty (implicit).
              
              ...
              
              This code requires WindowsNT 5.1 or better, which means on the client
              Windows XP or better, on the server Windows Server 2003 or better.
              
              ...
              
              All the options above are - like the whole Windows support -
              experimental.
              
              A lot is still TODO, e.g.:
              
                - Wide Character support (display is workable, but input untested)
                  The Win32Con driver should actually only use Unicode in the
                  future.
                - Thread support (locking). If using TDM toolchain this is done by
                  configuring pthreads.
                - A GUI console driver
                - Support for Terminals attached via a serial port (via terminfo)
                - Support for networked Terminal connections (via terminfo)
                - Workarounds for MinGW's filesystem access are necessary to make infocmp
                  work (though tic works).
              
              To support terminfo, we would need to have an ioctl() simulation for the
              serial and networked terminals.


              Короче, отсутствие переменной TERM — это специальный случай.
              Ответить
      • >> Первая хуйня в хуевом макросе
        >> #define msleep(msec) usleep(msec*1000)

        Да, макросы — это зло.

        Кстати, если обёртку сделать как функцию с атрибутом inline, то оптимизатор уберёт лишний код.

        >> Вторая хуйня в getstr() - эта хуйня настолько же небезопасна, как и gets().

        int getnstr(char *str, int n) — это тоже немножко костыльное решение. Сколько я должен выделить байт, чтобы не обидеть пользователя? Выделю я 30 букв под ФИО, а ко мне придёт Филипп Ауреол Теофраст Бомбаст фон Гогенгейм.

        На мой взгляд нужна функция, которая сама умеет реаллоцировать место под строку, если его не хватает. Вызов realloc для маленькой строки на гигагерцовых машинах может занимать намного больше времени, чем интервал между нажатием клавиш?
        Ответить
      • В общем, #if defined(_WIN32) в этом коде — уже говно, потому что ncurses портировали только под MinGW, а там и <unistd.h> есть.

        Вот pdcurses были и под Borland C, и под MSVC, и ещё под кучу компиляторов, а за порт ncurses мало кто брался.
        Ответить
        • показать все, что скрытоvanished
          Ответить
          • А это что такое?
            Ответить
          • Ты про поддержку ANSI-последовательностей? Так есть же ConEmu, Console2, TCC (бывший 4NT, наследник 4DOS, не путать с компилятором), которые работают на этих ваших XP.

            В Windows 3.11 консольных функций вообще нет, там консоль исключительно для запуска досовских программ. Даже под Win32s консольные программы запускаются... без консоли, т. е. в файлы писать могут, а на экран ничего не выводят. Для Windows 3.11 нужно писать отдельный эмулятор терминала, который открывает окно и рисует в нём текст (и такие эмуляторы уже существуют).

            А PDCurses не требует поддержки ESC-последовательностей, там такой же хак, как и в ncurses для MinGW.
            Ответить
            • Кстати, при запуске FAR из-под ConEmu наблюдаются странные глюки. Видимо, и FAR, и ConEmu используют какие-то грязные приёмы, и в данном сочетании они мешают друг другу.
              Ответить
              • показать все, что скрытоvanished
                Ответить
                • Да, ФАР в conemu запускается и даже что-то можно в нём делать. Но иногда выскакивают глюки. Я уже точно не помню, какие, потому что хлебнув дерьма, перестал запускать ФАР из-под него.

                  %TERM% нет, но conemu поддерживает какой-то набор ESC-последовательностей, типа того, который поддерживал ANSI.SYS. По крайней мере, какое-то прыщеговно при запуске из-под conemu раскрашивает экран.
                  Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоА можете получить с клавиатуры русскую букву?

      CharToOemBuff
      Ответить
    • Ещё одна хуйня: getstr из ncurses у каждого введённого символа оставляет только семь младших битов. Если набирать символы за пределами базовой латиницы, вводится мусор.

      В общем, ненужное прыщеговно.
      Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий