Getch () не читает ввод

Я пробовал использовать getch () и kbhit () для чтения ввода пользователя, но, похоже, он не распознает нажатие клавиши.

void main(){
    printf("start\n");
    while (1){
        if (kbhit() == 1){
            printf("in\n");
            int k = getch();
            printf("k: %d\n", k);
        }
    }
}

Этот код печатает «start» и ничего не печатает при нажатии клавиши. Мне не удалось использовать getch () для чтения и печати даже одного символа без цикла.

Не могу воспроизвести. Но с другой стороны, kbhit() и getch() не являются стандартными функциями, поэтому их характеристики могут отличаться. Возможно, вы могли бы в качестве первого шага привести свой стандарт кода в соответствие с int main(void) { и return 0; в конце main. Откуда берутся эти функции kbhit() и getch()? Какой компилятор и платформа?

Swordfish 26.11.2018 23:41

Вы пробовали if (kbhit()) без сравнения с 1?

Swordfish 26.11.2018 23:42

Если я помню, они являются частью conio.h, который есть в старых компиляторах для Windows, таких как Turbo C. Конечно, это взрыв из прошлого, когда появилась эта функция, которой я не пользовался уже 20 лет.

paddy 26.11.2018 23:42

@paddy <conio.h> по-прежнему поставляется с Visual Studio в 2018 году.

Swordfish 26.11.2018 23:43

Ха! Это так? Думаю, я перешел к использованию Win API и больше никогда не смотрел на этот заголовок.

paddy 26.11.2018 23:44

@paddy Теперь вы знаете, что делать, когда чувствуете ностальгию;)

Swordfish 26.11.2018 23:45

@Swordfish Они взяты из версии WinBGI моего университета. Я использую VS2013 для компиляции кода. Мне удалось заставить их работать в другом коде, где я также использовал void main () и использовал их в цикле, который я вставил. Единственное отличие состоит в том, что программа выполняла и другие действия в цикле while (рисовала круги и перемещала их, используя вводимые пользователем данные).

absalon 26.11.2018 23:52

Текущий ответ правильный (kbhit возвращает ненулевое значение, которое нет обязательно совпадает с 1). Вам также следует проверить документацию для получить, поскольку ваша текущая логика немного странная. Обычно вы должны использовать возвращаемое значение, чтобы проверить наличие управляющего символа и выполнить второй вызов getch. У вас также есть цикл занятости, который будет как сумасшедший крутиться на одном из ядер вашего процессора. Вы можете добавить туда небольшую задержку (например, Sleep(30)) для здравомыслия.

paddy 26.11.2018 23:55

Существует множество библиотек под названием WinBGI и т.п. Разве ваш университет не предоставляет для этого документацию? Вы уверены, что kbhit() возвращает 1? Вы пробовали if (kbhit()) без сравнения с 0? - где я также использовал void main () - Неважно, что компилирует Visual Sudio 2013 или нет, это int main(void) в соответствии со стандартом языка C. Пожалуйста, используйте это. Кроме того: почему вы используете VS2013 в 2018 году? Visual Studio 2019 скоро выйдет.

Swordfish 26.11.2018 23:57

... так что это должен быть if (kbhit()), и обратите внимание, что getch возвращает "escape" значения для функциональных клавиш, клавиш курсора и т. д., которые должны быть обнаружены и если так вызываются дважды. Вы можете написать простую тестовую программу, чтобы проверить это.

Weather Vane 26.11.2018 23:57

Во время недавних археологических раскопок в Кремниевой долине археологи были рады найти руководство по библиотеке BGI Borland Turbo C. C14 датировал его 1988 годом. Он был в плохих условиях, но среди вещей, которые все еще можно было прочитать, была страница kbhit, на которой говорилось: «Возвращаемое значение Истинное (ненулевое), если есть символ во входном буфере, в противном случае - ложь». Если вы используете эти функции в археологических целях, что может быть единственной причиной их использования, замените if (kbhit() == 1) на if (kbhit()).

Lundin 27.11.2018 11:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
11
690
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Опубликованный код не компилируется!

Для main() существует только 2 действительных подписи, независимо от того, что может позволить Visual Studio:

int main( void )
int main( int argc, char *argv[] )

Обратите внимание, что они оба возвращают int, а не void.

в опубликованном коде отсутствуют необходимые операторы #include

задавая вопрос во время выполнения, как и в этом вопросе, опубликуйте [mcve], чтобы мы могли воссоздать проблему.

функция: kbhit() возвращает ненулевое значение (не обязательно 1) при нажатии клавиши.

Предложить:

#include <stdio.h>
#include <conio.h>  // note: this is a nonstandard header
                    // in Windows, so it is not portable
int main( void )
{
    printf("start\n");

    while (1)
    {
        if ( kbhit() )
        {
            printf( "in\n" );
            int k = getch();
            printf( "k: %d\n", k );
        }
    }
}

С каких это пор C возвращает значение 0 по умолчанию для main()?

Swordfish 26.11.2018 23:52

@Swordfish, так как последние несколько лет. Я не уверен в дате создания, но, по крайней мере, с C11.

user3629249 26.11.2018 23:55
main - единственная непустая функция C, которой не нужно явно возвращать значение, и предупреждения компилятора нет :)
Weather Vane 26.11.2018 23:56
но по крайней мере с C11 - Ах, спасибо. @WeatherVane IIRC не требуется никаких функций в C для возврата чего-либо, если значение не используется вызывающей стороной.
Swordfish 27.11.2018 00:01

Это работает с <conio.h>, но не с пользовательской библиотекой, которую я должен использовать, поэтому я думаю, что теперь мне нужно покопаться в ней и выяснить, почему. Спасибо за помощь :)

absalon 27.11.2018 00:05

@Swordfish, современный компилятор выдаст предупреждающее сообщение, если функция, отличная от void, не вернет значение.

user3629249 27.11.2018 00:05

Было бы намного проще ответить, если бы OP опубликовал минимальный воспроизводимый пример

user3629249 27.11.2018 00:06

@ user3629249 Я говорил не о предупреждениях компилятора, а о языковых требованиях.

Swordfish 27.11.2018 00:09

@absalon На вашем месте я бы отказался работать с недокументированным программным обеспечением, которое вам дали, и взял бы один из многих имеющихся WinBGI с документацией. Вы всегда можете сказать, что ваша собака съела оригинал;) (если, конечно, у вас нет собаки, кроме кошки. В этом случае вы должны знать, что каждый раз, когда вы используете void main(), котенок где-то умирает :()

Swordfish 27.11.2018 00:10

@Swordfish, которую я последний раз проверял, не возвращается, это UB. Если вам повезет, вы получите ошибку, но если вы используете clang, вы получите простое предупреждение и неверную инструкцию, кому не нравится работать с ошибками времени выполнения в C.

van dench 27.11.2018 00:27

@vandench Я только что проверил. Он был изменен с C99: TC3 на C11.

Swordfish 27.11.2018 00:32

@Swordfish Нет, он был добавлен в C99 5.1.2.2.3 reaching the } that terminates the main function returns a value of 0.. Так что он существует уже 20 лет ...

Lundin 27.11.2018 10:50

@Lundin Нет - когда это «Нет» касается комментария над вашим ... стало обязательным возвращать sth. from функции (кроме main()), не возвращающие void в C++ 11. Я не говорил о дефолтном return 0; для main().

Swordfish 27.11.2018 13:09

Другие вопросы по теме