12-09-2005 10:15 программистское
Что за странный тип данных unsigned char?
Если написать printf("%u", unChar), где unChar -- это unsigned char стрелка влево, то выведется вот что: 22475. Два числа (224,75) записаные подряд. Это как вообще?

Цель -- перехватить нажатие стрелки с клавиатуры, я пока не врубаюсь как.
Комментарии:
12-09-2005 11:11
Камрад с блокнотиком
unsigned char — это беззнаковый целочисленный тип размером в один символ. В зависимости от платформы символ может быть однобайтовым или многобайтовым.

При передаче в printf все [[un]signed] char’ы и [[un]signed] short’ы расширяются до int’а или unsigned int’а. С числовым значением при этом ничего не происходит.

Стрелка влево — понятие растяжимое. Это символ 0x1B ASCII, или это символ U+2190 LEFTWARDS ARROW Unicode на платформе, где Unicode — основное представление символов?

Клавиатуры не существует (в рамках C/C++). Есть стандартный входной файл stdin (C) и стандартный входной поток std::cin (C++). Нажатия клавиш на этом уровне не перехватываются.

Нажатия клавиш можно перехватить платформо- и терминалозависимыми средствами. В старом добром DOS, например, клавиши стрелок генерировали по два символа: первый был, если мне не изменяет память, '\0' (0x0, 0), а второй — 'H' (0x48, 72), 'K' (0x4B, 75), 'M' (0x4D, 77) и 'P' (0x50, 80) для стрелок соответственно вверх, влево, вправо, вниз. Клавиши F1–F10 и, кажется, различные Alt+буквы/цифры тоже давали коды примерно в этом формате.

У тебя в системе, похоже, клавиши стрелок выдают двухсимвольные последовательности, начинающиеся с 0xE0 (224). Рекомендую при выводе разделять числа чем-нибудь — пробелом, запятой, переводом строки.

bool handleKey(char ch);
bool handleExtendedKey(char ch);

int main(int, char**)
{
  while (true)
  {
    char ch = getch(); // или чем там читается 
    // консольный ввод на этой платформе

    if (ch != 0 /*или 0xE0, или с чего ещё начинаются 
      последовательности для расширенных клавиш */) 
    {
      if (!handleKey(ch)) break;
    }
    else
      if (!handleExtendedKey(getch())) break;
  }
  return 0;
}

bool handleKey(char ch)
{
  std::cout << ch;
  return true;
}

static const char kUpArrow = 'H';
static const char kDownArrow = 'P';
static const char kLeftArrow = 'K';
static const char kRightArrow = 'M';
static const char kF10 = 'D';

bool handleExtendedKey(char ch)
{
  switch (ch)
  {
  case kUpArrow:
    std::cout << "[Up]";
    return true;
  case kLeftArrow:
    std::cout << "[Left]";
    return true;
  case kRightArrow:
    std::cout << "[Right]";
    return true;
  case kDownArrow:
    std::cout << "[Down]";
    return true;
  case kF10:
    std::cout << "[F10]";
    return false; // exit main loop
  default:
    std::cout << "[Unknown key]";
    return true;
}

Или, скажем, так…
int main(int, char**)
{
  std::ofstream keynames("keynames.h");
  while (true)
  {
    unsigned char ch = getch();
    if (ch == 'q') return 0;
    if (ch == 0xE0)
    {
      unsigned char ch2 = getch();
      std::cout << "Extended key 0xE0 " << std::hex << ch2 << ", enter a name: ";
      std::string name;
      std::cin >> name;
      keynames << "static const unsigned char k" << name << 
        " = 0x" << std::hex << ch2 << ";\n";
    }
  }
}
12-09-2005 11:22
Камрад
Ух! Спасибо за лекцию, хотя я вроде уже почти разобрался (MS Visual C++ у меня)
Получается что один и тот же символ вроде бы как равен двум значениям (хотя if( (ch == 75) && (ch == 224)) все равно дает ложь).
Вот это вот по-моему и есть тот самый ужас-ужас-ужас.
12-09-2005 11:29
Камрад с блокнотиком
Получается что один и тот же символ вроде бы как равен двум значениям
Ничего подобного. Нет никакого одного символа. Есть два символа, которые приходят в программу по очереди, один за другим. А то, что вся эта последовательность генерируется одной клавишей, ну так что ж тут такого?
12-09-2005 11:32
Камрад
Centaur
А почему условие ложь возвращает?
Щас попробую по-твоему сделать.
12-09-2005 12:00
Камрад с блокнотиком
Которое условие? Вот это? (ch == 75) && (ch == 224)
Потому что ch не может одновременно равняться 75 и 224 — из этого следовало бы, что 75 == 224, чего на самом деле в природе не наблюдается.

getch() — это не функция в чистом математическом смысле этого слова, у неё есть побочный эффект, и нельзя ожидать, что два последовательных вызова её будут эквивалентны одному вызову, или что они дадут один и тот же результат.
12-09-2005 12:07
Камрад
Всё! Добил. Победа разума
Спасибо!
Закрыть