std :: getline из std :: cin - история ввода с помощью кнопки вверх / вниз, не работающая в linux [duplicate]

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

8
задан SplatFace Development 12 July 2014 в 02:21
поделиться

4 ответа

#include <conio.h>
#include <iostream>
using namespace std;

#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77

int main()
{
    int c = 0;
    while(1)
    {
        c = 0;

        switch((c=getch())) {
        case KEY_UP:
            cout << endl << "Up" << endl;//key up
            break;
        case KEY_DOWN:
            cout << endl << "Down" << endl;   // key down
            break;
        case KEY_LEFT:
            cout << endl << "Left" << endl;  // key left
            break;
        case KEY_RIGHT:
            cout << endl << "Right" << endl;  // key right
            break;
        default:
            cout << endl << "null" << endl;  // not arrow
            break;
        }

    }

    return 0;
}

выводится следующим образом:

Up

Down

Right

Left

Up

Left

Right

Right

Up

обнаружена клавиша со стрелкой!

12
ответ дан temarsden 19 August 2018 в 06:28
поделиться
  • 1
    Спасибо! Я протестировал ваш точный код, и он отлично работал (минус одна отсутствующая фигурная скобка), и это дало мне рабочий результат! Теперь я просто поставлю его в свой код и посмотрю, продолжит ли он работу – SplatFace Development 12 July 2014 в 02:53
  • 2
    Прекрасно работает! Благодаря! – SplatFace Development 12 July 2014 в 03:01
  • 3
    Visual Studio 2013 говорит мне использовать _getch (), поскольку getch () устарел. «Предупреждение C4996:« getch »: имя POSIX для этого элемента устарело. Вместо этого используйте имя ISO C ++: _getch. & Quot; – aj.toulan 11 November 2015 в 18:12
  • 4
    Как насчет разных мест? Будет ли это работать и на клавиатуре с китайской раскладкой? – normanius 27 October 2016 в 15:49

Вот альтернативный способ сделать это без getch () с помощью событий (хорошо прокомментирован, и я попытался сделать это так просто, как мог)

#include <iostream>
#include <Windows.h>

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

    HANDLE rhnd = GetStdHandle(STD_INPUT_HANDLE);  // handle to read console

    DWORD Events = 0;     // Event count
    DWORD EventsRead = 0; // Events read from console

    bool Running = true;

    //programs main loop
    while(Running) {

        // gets the systems current "event" count
        GetNumberOfConsoleInputEvents(rhnd, &Events);

        if(Events != 0){ // if something happened we will handle the events we want

            // create event buffer the size of how many Events
            INPUT_RECORD eventBuffer[Events];

            // fills the event buffer with the events and saves count in EventsRead
            ReadConsoleInput(rhnd, eventBuffer, Events, &EventsRead);

            // loop through the event buffer using the saved count
            for(DWORD i = 0; i < EventsRead; ++i){

                // check if event[i] is a key event && if so is a press not a release
                if(eventBuffer[i].EventType == KEY_EVENT && eventBuffer[i].Event.KeyEvent.bKeyDown){

                    // check if the key press was an arrow key
                    switch(eventBuffer[i].Event.KeyEvent.wVirtualKeyCode){
                        case VK_LEFT:
                        case VK_RIGHT:
                        case VK_UP:
                        case VK_DOWN:   // if any arrow key was pressed break here
                            std::cout<< "arrow key pressed.\n";
                            break;

                        case VK_ESCAPE: // if escape key was pressed end program loop
                            std::cout<< "escape key pressed.\n";
                            Running = false;
                            break;

                        default:        // no handled cases where pressed 
                            std::cout<< "key not handled pressed.\n";
                            break;
                    }
                }

            } // end EventsRead loop

        }

    } // end program loop

    return 0;
}

(Спасибо комментатору, я знаю, что этот код не является стандартным, хотя он будет работать, если вы скомпилируете с g++, больше информации в комментариях)

4
ответ дан James 19 August 2018 в 06:28
поделиться
  • 1
    Этот код не будет работать на INPUT_RECORD eventBuffer[Events];, потому что Events не является константой. Но вы можете читать события один за другим. – vladon 30 May 2015 в 07:27
  • 2
    Я не знал, что Events должен быть const. Я просто скомпилировал его (с g++), и он появляется для запуска, как я и предполагал ... Во что бы то ни стало, если это сломанный код, я попытаюсь исправить его или (скорее всего) просто удалить ответ, но прежде чем я хочу узнать, как именно этот код должен потерпеть неудачу, поэтому я могу попытаться это увидеть сам. – James 30 May 2015 в 16:44
  • 3
    динамические массивы - это расширение g ++, а не стандартное c ++ – vladon 30 May 2015 в 20:09
  • 4
    Ах, я вижу, спасибо за информацию, я думаю, что просто сделаю редактирование. – James 31 May 2015 в 02:28
// Example for inputting a single keystroke in C++ on Linux
// by Adam Pierce <adam@doctort.org> on http://www.doctort.org/adam/nerd-notes/reading-single-keystroke-on-linux.html
// This code is freeware. You are free to copy and modify it any way you like.
// Modify by me Putra Kusaeri


#include <iostream>
#include <termios.h>
#define STDIN_FILENO 0
using namespace std;
int main()
{
// Black magic to prevent Linux from buffering keystrokes.
    struct termios t;
    tcgetattr(STDIN_FILENO, &t);
    t.c_lflag &= ~ICANON;
    tcsetattr(STDIN_FILENO, TCSANOW, &t);

// Once the buffering is turned off, the rest is simple.
    cout << "Enter a character: ";
    char c,d,e;
    cin >> c;
    cin >> d;
    cin >> e;
    cout << "\nYour character was ";
// Using 3 char type, Cause up down right left consist with 3 character
    if ((c==27)&&(d=91)) {
        if (e==65) { cout << "UP";}
        if (e==66) { cout << "DOWN";}
        if (e==67) { cout << "RIGHT";}
        if (e==68) { cout << "LEFT";}
    }
    return 0;
}
1
ответ дан Putra Kusaeri 19 August 2018 в 06:28
поделиться
1
ответ дан user93353 19 August 2018 в 06:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: