1. C++ / Говнокод #4211

    +151

    1. 1
    2. 2
    3. 3
    char line[10];
    cout<<"Press any key to exit"<<endl;
    cin.getline(line,9);

    Очередной перл из решений кандидатских задач.
    Видимо в военное время количество символов, генерируемых одной клавишей, может достигать 9. :)

    Запостил: Lexey, 09 Сентября 2010

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

    • Наверное вас сбила с толку надпись Press any key to exit.
      Потому что getline читает не 1-н символ, а их последовательность. вроде тут всё корректно.
      Ответить
      • Я как бы в курсе, что делает getline. И это еще один косяк этого кода. Вместо того, чтобы ждать нажатия любой клавиши, он ждет до нажатия Enter (независимо от количества запрошенных символов).
        Ответить
        • Видимо таки не в курсе.

          `basic_istream<>::getline` завершает ввод при выполнении одного из трех условий:
          1) возникло условие "конец файла" (в потоке выставляется `eofbit`)
          2) прочитан символ окончания ввода (в данном случае - '\n'),
          3) прочитано n-1 символов (в потоке выставляется `failbit`)

          В том, что данный код - говнокод сомневаться, разумеется, не приходится. Возможно "аффтар" понимал, что пользователь будет недоуменно нажимать, скажем, пробел и, чтобы пользователь не мучался до второго пришествия, ограничил длину ввода 8 символами. Т.е. если пользователь не догадался сразу нажать именно на Enter, то его мучения с разнообразными any key закончатся после 8-ми нажатий.

          Тем не менее умиляет использования размера 9. Если уж буфер выбран размера 10, то именно 10 надо было и передавать в `getline` (`sizeof line` например). Хотя, конечно, бессмысленно рассуждать о размере тогда, когда сам подход крив донельзя.
          Ответить
          • 8 человек сомневаются в том, что это говнокод. Большинство не может ошибаться!
            Ответить
            • Кстати, кому принадлежит фраза: "Всё таки в говне что-то есть. Миллионы мух не могут ошибаться"? Станиславу Лему?
              Ответить
              • Поисковик привёл в Луркоморье. Там пишут, что автор Станислав Ежи Лец.
                В Викицитатнике есть цитата: http://ru.wikiquote.org/wiki/Лец
                Но нет ссылки на произведение.
                Ответить
                • Нас обманывают. На польских сайтах пишут, что автор Вальдемар Лысяк:
                  http://tinyurl.com/35o4uwc
                  Однако, из русского раздела Википедии статья о нём удалена.
                  Ответить
                  • Кем-то из того пресловутого миллиона мух, к гадалке не ходи!
                    Ответить
          • >Видимо таки не в курсе.

            Нет, видимо все-таки в курсе.
            1) тут мимо кассы, ибо ввод идет с клавиатуры.
            2) Именно этот вариант тут дает то, что задумывалось - завершение программы.
            3) Это все замечательно, только этого не произойдет пока не встретиться \n или конец файла. Так что практической пользы от этого уточнения в данном случае - 0.

            >Возможно "аффтар" понимал, что пользователь будет недоуменно нажимать, скажем, пробел и, чтобы пользователь не мучался до второго пришествия, ограничил длину ввода 8 символами. Т.е. если пользователь не догадался сразу нажать именно на Enter, то его мучения с разнообразными any key закончатся после 8-ми нажатий.

            Юзер может хоть до посинения жать пробел. Ничего не будет, пока он не нажмет Enter.
            Ответить
            • Правильное замечание. Однако странно видеть наезд на первый вариант, ибо операционные системы традиционно поддерживают создание условия "конец файла" в стандартном потоке ввода с клавиатуры. Ctrl+Z в Windows, Ctrl+D в *nix и клонах. (Разумеется, ожидать этого от простого пользователя не приходится.)
              Ответить
              • Я сначала хотел сделать на это оговорку, но потом проверил. В Винде Ctrl-Z тоже не работает, пока Enter не нажмешь.
                Ответить
                • А это уже зависит от реализации кокретной библиотеки времени выполнения, а не от "Винды". Библиотека, идущая с GCC, например, прерывает ожидание по Ctrl-Z, не дожидаясь нажатия Enter. Библиотека, идущая с MSVC++, действительно ждет Enter даже после Ctrl-Z.
                  Ответить
    • Press any RETURN key to exit
      Ответить
      • «Any key — это третий ентер слева в первом ряду». Бородатая шутка про IBM-несовместимые клавиатуры.
        Ответить
        • ну, на самом деле "any key" находится на корпусе системника...
          Ответить
          • http://www.getdigital.de/images/actionshots/t4/ANY_DSCN0366.jpg
            --
            спец предложение от "logitech"
            Ответить
            • что-то не понял, на каких кнопках оно висит. по идее, там (в среднем столбце) находятся хоум и энд, но в левом столбце на нижней кнопке тоже вроде написано "End"... или кнопки переставили...
              Ответить
              • в таких случаях предусмотрена красная кнопка выше... :)
                Ответить
                • в таких случаях остается использовать вот это
                  http://www.getdigital.de/images/actionshots/t4/AnyKey_Morse.JPG
                  Ответить
              • Это расовая немецкая клавиатура. Там написано «Entf» от слова «entfernen» — «удалить». Я однажды видел французскую клавиатуру, на которой все клавиши тоже были переведены.
                А на русский почему-то перевели только на ЕС-1840.
                Ответить
                • Я видел клавиши "возврат" (return)

                  Кстати лучшая рассовая немецкая клава у меня:

                  http://www.daskeyboard.com/model-s-ultimate/
                  Ответить
                  • пффф... http://upload.wikimedia.org/wikipedia/commons/5/57/ModelM.jpg
                    Ответить
                    • классика от ибм) отличная была, кстати.

                      А в современных мамах иногда уже даже i8042-то нет... И даже его эмуляция в USB стала необязательной
                      Ответить
                      • почему была, у меня еще экземпляр остался :)

                        кстати, их даже вроде бы сейчас по лицензии кто-то делает
                        "Unicomp has had difficulty making them profitable because they rarely break" (педивикия)
                        Ответить
                  • Фап!

                    Вопрос немного не в тему, а на клавиши Вы что-то наклеили или так оставили?:)
                    Ответить
                    • фу, зачем клеять?)))))
                      конечно, так оставил) довольно редко промахиваюсь)

                      а как она стучит....
                      Ответить
                  • Дозрел купить, пока две. Могу прихватить еще несколько — всяко доставка дешевле будет. Не интересуют? Можно скооперироваться.
                    Ответить
                • У меня тоже расовая немецкая, кстати. Вот мой убитый ноут:
                  http://www.gamedev.ru/files/images/dsc00002.jpg
                  Ответить
                • и очень хорошо, что не перевели на русский.
                  а то у всех секретарш и прочих чайников кроме вопроса "А где Any Key?" появились бы вопросы типа "А где Esc?", "А где Home?", "А где Insert?", "А где Caps Lock?"...
                  кроме того, перевод был бы ужасным, как обычно.
                  Ответить
                  • А немцы и французы спрашивают: «Где Delete?»?
                    Ведь у них «Entfernen» и «Annulaire» соответственно.
                    Ответить
    • Все просто:
      В военное время могут трястись руки и получаться дребезг.
      На клавиатуру может упасть бездыханное тело (или еще-не-бездыханное тело будет нажимать кнопки головой).
      А размер буфера отражает серьезность намерений — человек действительно хочет нажать кнопку:)
      Ответить
    • в мире freepascal такая хрень часто встречается, потому что процедура ждать строки из stdin - стандартная, а ждать любой кнопки - кроссплатформенной функции нет
      Ответить
      • repeat until KeyPressed;

        Или где-то не работает?
        Или может это не обязательно stdin? Вот только когда общение идёт с пользователем, KeyPressed должно хватить
        Ответить
        • facepalm.pas
          я сказал:
          > кроссплатформенной
          а школьным курсом Turbo Pascal 7.0 ты блеснул,
          Write('Press any key to exit...');
          repeat until KeyPressed;
          Halt;

          передаст неочищенный буфер клавиатуры родителю. Самый смак будет, если глупый юзер вместо any key жмакнул ↵, а родитель - NC или любая другая оболочка, которая по ↵ запускает прогу еще раз :-D
          Ответить
          • Ага, а самое интересное, что программ, оставляющих код в буфере, немало. Особенно интересно, если в буфере «DEL *.* /S /F /Q».

            Модуль Crt — УГ редкостное. KeyPressed не реагирует на F11, F12 и ещё на кучу символов, а ReadKey для некоторых клавишей нужно вызывать два раза. Проще написать свои функции, чем подстраиваться под Crt. Не потому ли у него куча альтернатив?
            Я делал так:
            Writeln('Press any key');
            asm
              mov ax, 10h
              int 16h
            end;

            Естественно, для виндовой версии этот код придётся переписывать.
            Ответить
            • "ReadKey для некоторых клавишей нужно вызывать два раза"
              ну да, как и документации
              http://www.freepascal.org/docs-html/rtl/crt/readkey.html
              Было бы хуже если бы этого не было написано.

              >Я делал так
              Вроде freepascal обсуждаем, а не то как кто-то когда то делал под TP
              Ответить
              • Кэп не ошибается! А TP — просто первое, что я вспомнил.
                Ответить
            • > программ, оставляющих код в буфере
              я залез в Джордейна, а у него прямо эта техника и описана

              насчет ReadKey и расширенных клавиш у меня к Crt нареканий нет (если вернула #0 - изволь прочитать скан-код), а вот, помнится там был замечательный busy-loop для того, чтобы высчитать, сколько итераций можно сделать между прерываниями времени суток (калибровка для Delay) результат хранился в слове и на быстрых процах линковка с Crt автоматически означала падение с divide by zero. Вот это да, сильно. И оф. патча не было. К счастью, сырцы RTL прилагались.
              Ответить
              • >я залез в Джордейна, а у него прямо эта техника и описана

                К чему это? речь шла про кроссплатформеность

                > divide by zero
                это по-моему error 200, или 220 уже не помню.
                Но вроде была небольшая программка, patchpas.com по-моему, она могла пропатчить уже готовый exe, на тот случай, если исходников нет..

                >в мире freepascal такая хрень часто встречается, потому что процедура ждать строки из stdin - стандартная, а ждать любой кнопки - кроссплатформенной функции нет

                Так что, есть?
                Ответить
                • > К чему это?
                  Видимо, здесь обсуждают решение для DOS/Realmode

                  > вроде была небольшая программка, patchpas.com по-моему,
                  > она могла пропатчить уже готовый exe
                  Даа, линковать кривую RTL и потом патчить исполняемый модуль - это годное, системное решение
                  Лично мне попалась не такая уж небольшая и вдобавок потребовала DOS4GW
                  Кстати, из описания бага следует, что патч RTL увеличивает размер кода, и утилита для пост-обработки бинарей должна быть либо очень умной, либо должна изговнякать код от которого зависит Delay

                  -CR        Verify object method call validity
                        -Cs<n>     Set stack size to <n>
                        -Ct        Stack checking
                  *** press enter ***
                  sssssssssssssssssssssssssslolwtf this is fpc 2.2.4 output, eat a dick

                  на какие платформы Crt.KeyPressed, Crt.ReadKey не портировали предлагаю найти самостоятельно, ОК? (без подвоха, такие есть)
                  Ответить
                  • >> она могла пропатчить уже готовый exe
                    >Даа, линковать кривую RTL и потом патчить исполняемый модуль - это годное, системное решение
                    "А ещё тролопотамусы прикидываются кактусами, отвечая на высказывания выкидывая из них значимые части, например:"
                    >>она могла пропатчить уже готовый exe, на тот случай, если исходников нет

                    >не портировали предлагаю найти самостоятельно, ОК?
                    Мне это не надо.
                    >а ждать любой кнопки - кроссплатформенной функции нет
                    Я показал, что всё таки есть, если хочешь оспорить и показать что на некоторых платформах не реализовано - ищи сам.
                    Ответить
                    • Мне, как программисту, такие случаи ни хуя неинтересны. Если уж настолько важен бинарь от проебанных исходников, есть решения по-приличнее.

                      > > а ждать любой кнопки - кроссплатформенной функции нет
                      > Я показал, что всё таки есть
                      Ну-ка, ну-ка, посмотрим
                      ищи слово caveats и читай вокруг
                      это был совет
                      Ответить
                      • >Мне, как программисту, такие случаи ни хуя неинтересны.
                        >Если уж настолько важен бинарь от проебанных исходников, есть решения по-приличнее.
                        Ну да, ты наверное относишься к клану программистов, которые никогда не используют чужие программы - ездят исключительно на своих велосипедах.
                        Ответить
                        • Ох, LOL! Нет, я совершенно определенно не отношусь к слоупокам, юзающим нечто архиважное, автор коего:
                          * собрал седьмым турбопаскалем под DOS
                          * за 15 лет вообще свое творение не трогал
                          * не отдал сырцы при этом

                          Я тя научу, что делать. В третий день новой луны, семижды перекрестясь, подходишь к ларьку, берешь два пива и тюбик кольдкрема. Потом идешь к автору и обратив ягодицы к востоку и произносишь след. заговор: «чуваак! твоя тулза на моем проце падает! пересобери её virtual pascal`ем!»
                          Ответить
                          • тише,тише. Тебя где-то что-то уязвило?

                            >>она могла пропатчить
                            >* за 15 лет вообще свое творение не трогал
                            я не говорил того, что пользуюсь ей по сей день
                            Ответить
                            • а хули ли на пол-треда размазываешь сантабарбару про сверхценный кусок 16-битного abandonware?
                              Ответить
                              • - Николай Николаевич, вам слово.
                                -"Мы продолжаем наш цикл передач про тролопотамусов. Тролопотамусы, в силу своих пристрастий любят затягивать дискуссии, коверкая высказывания участников дискуссии. Но тем не менее, если дискуссия складывается не в их пользу, выставляя их дураками, их ограниченные умственные способности не дают им осознать того, что они виновники, как они это называют "сантабарбары" "
                                Ответить
                    • > А ещё тролопотамусы прикидываются кактусами

                      Как, как Вы меня назвали?
                      Ответить
                      • впервые на сцене - кактус - некрофил!
                        Ответить
                        • Не некрофил, а некромант!
                          Ответить
                          • Поднимите Царя, пожалуйста.
                            Ответить
                            • Я не волшебник, я только учусь. Пока у меня получается только поднимать павшие говнокоды. Но я обязательно что-нибудь придумаю.

                              P.S. А что с Царём?
                              Ответить
                              • Царь пропал. Поговаривают, что умер.
                                Ответить
                                • Вижу Царя... Прошлым летом он ещё появлялся в этих ваших интернетах:
                                  https://gist.github.com/superhackkiller1997

                                  Дальше... Пока не вижу... Ждите...
                                  Ответить
                                  • >> Ждите...
                                    http://ololo.fm/search/Emanuel+Hovaghimian/Spring+(Palabras)
                                    Ответить
                                • не выдержало сердце нового стандарта...
                                  Ответить
            • Да, в том, что в буфер Ф11 и Ф12 не заносятся, виноват модуль ЦРТ. ЛОЛ.
              Ответить
          • ты говорил про freepascal?
            Прежде чем написать, я посмотрел сюда http://www.freepascal.org/docs-html/rtl/crt/keypressed.html
            И если ты не заметил, я спросил явно
            >Или где-то не работает?

            А кто сказал что после
            repeat until KeyPressed;
            не надо очищать буфер? Если ты так говнокодишь, после школьного курса TP 7.0, то давай ещё говнокоды студию
            Ответить
            • > А кто сказал что после
              Поздно, мистер Баттхёрт!
              Ответить
              • Кстати, до тоже почиститься не мешало бы!
                Ответить
                • var
                    Head: Word absolute $0040:$001A;
                    Tail: Word absolute $0040:$001C;
                    Buffer: array[0..15] of Word absolute $0040:$001E;
                  { ... }
                    { почиститься }
                    Head := Tail;

                  во, раскопал, хотя пованивает, ибо INT 09 может всё испортить
                  Ответить
                  • Head := Tail;
                    Это из разряда в рот мне ноги хвост!
                    Ответить
                  • Вротмненоги Вголовумнехвост не прокатит. Crt использует функцию ДОС, а не БИОС, поэтому и приходится опрашивать ReadKey по два раза для некоторых клавишей. У ДОСа есть свой буфер, в котором может остаться код «расширенной» клавиши. Вот так чистятся в TP:
                    if KeyPressed then if ReadKey=#0 then ReadKey;

                    или так:
                    while KeyPressed do if ReadKey=#0 then ReadKey;

                    Но, как я уже писал, стандартная KeyPressed ущербна, поэтому её надо переписывать.
                    Ответить
                    • ; Return true if key is available
                      
                      KeyPressed:
                              CMP     ScanCode,0
                              JNE     @@1
                              MOV     AH,1
                              INT     16H

                      ы?
                      Ответить
                      • Не понял, переведите!
                        Кто такие ScanCode и @@1? Кусок из Турбовижен?
                        Кстати, чтобы реагировать на Ф11, Ф12 и всякие суперпуперклавиши современных клавиатур, нужно заменить 1 на 11h.
                        Ответить
                        • это не TV, исходник Crt. целиком:
                          ; Local workspace
                          
                          DelayCnt        DD      ?               ; тот самый счетчик, который переполняется 
                          ; ... 
                          ScanCode        DB      ?
                          ; ... 
                          
                          ; Return true if key is available
                          
                          KeyPressed:
                          
                                  CMP     ScanCode,0
                                  JNE     @@1
                                  MOV     AH,1
                                  INT     16H
                                  MOV     AL,0
                                  JE      @@2
                          @@1:    MOV     AL,1
                          @@2:    RETF
                          
                          ; Read character from keyboard
                          ; Out   AL = Character
                          
                          ReadKey:
                          
                                  MOV     AL,ScanCode
                                  MOV     ScanCode,0
                                  OR      AL,AL
                                  JNE     @@1
                                  XOR     AH,AH
                                  INT     16H
                                  OR      AL,AL
                                  JNE     @@1
                                  MOV     ScanCode,AH
                                  OR      AH,AH
                                  JNE     @@1
                                  MOV     AL,'C'-64
                          @@1:    CALL    BreakCheck
                                  RETF


                          Моя мысль о том, что не стали переделывать на INT 16 AH=10h,11h именно потому что расширенные клавиши не генерируют символов
                          Ответить
                          • DelayCnt DD ? ; это уже кусок патча, в оригинале DW
                            Ответить
                            • Точно! Именно так оно и было. Спасибо за напоминание.
                              Ответить
                    • Кэп?
                      Те кто программировал на TP, это и так знают. Другим же это нах не надо.

                      > Но, как я уже писал, стандартная KeyPressed ущербна, поэтому её надо переписывать.

                      Для кого? Зачем?
                      Ответить
                    • кстати, функция ReadKey возвращает тип Char, и Писании сказано: Reads a character from the keyboard. Поэтому, действительно, если нужен низкоуровневый ввод - надо писать свою. А пара KeyPressed/ReadKey - просто unprocessed input, дополняющий Readln
                      Ответить
              • Николай Дроздов: "Смотрите детишки, это зверушка семейства троллопотамуса.
                Когда у троллопотамусов заканчиваются аргументы, у них начинается словесный понос"
                Ответить
                • О! Понос на govnokod.ru - наверное в тему...
                  Ответить
                  • Название как бы намекает, что сайт профильный!
                    Ответить
                  • как говорят в одной маленькой восточноевропейской стране: Словения - это наш понос!
                    Ответить
        • > repeat until KeyPressed;

          Шикарно. А ReadKey; Не подойдет?
          Или раз уж раздел по C++
          getch();
          Ответить
          • Умеешь пиздячить неканонический режим?
            Геч, бля...
            Ответить
            • Что
              repeat until KeyPressed;
              что
              ReadKey;
              результат один. Только ReadKey; извлечет символ из буфера ввода.
              А чем тебе неканонический режим не нравится? Просто интересно.
              Ответить
              • Алё, я про геч. Его нет в unix, а автор кода суверенностью на 99% не сумеет его воспроизвести, так что он не канает. Иначе не было бы обсуждения.
                Ответить

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