Проблема в приведении типов при попытке написать код для WinAPI. Программа простенькая, для вывода таблицы умножения. Минус в том, что программа из учебника 2004 года по C++, возможно с тех пор многое изменилось.
Суть проблемы: возникает конфликт типов. Ошибка (активно) E0144 значение типа "const wchar_t *" нельзя использовать для инициализации сущности типа "TCHAR *"
также есть такие ошибки типа:
E0167 аргумент типа "const wchar_t *" несовместим с параметром типа "LPWSTR"
,
E0513 значение типа "const wchar_t *" нельзя присвоить сущности типа "TCHAR"
,
C2440 инициализация: невозможно преобразовать "const wchar_t [20]" в "TCHAR *"
Ещё не очень разбираюсь в Венгерской нотации и обозначениях при программировании на Windows, поэтому требуется помощь: "Что исправить, чтобы задумка автора кода работала?". Сам код ниже:
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <tchar.h>
#include <conio.h>
#include <iostream>
using namespace std;
BOOL PrintMsg(HANDLE hOut, LPCTSTR pMsg);
BOOL PrintStrings(HANDLE hOut, ...);
int main(char argc, char ** _targv) {
setlocale(LC_ALL, "");
int k;
HANDLE hStdOut;
hStdOut = CreateFile(_T("CONOUT$"), GENERIC_WRITE, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetConsoleMode(hStdOut, ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_PROCESSED_OUTPUT);
TCHAR * pr = _T("Введите множитель: ");
PrintMsg(hStdOut, pr);
cin >> k;
PrintMsg(hStdOut, CharUpper(_T("Таблица умножения:\n")));
TCHAR str1[3]; _itot(k, str1, 10); str1[2] = 0;
for (int i = 0; i <= 10; i++) {
TCHAR str2[3]; _itot(i, str2, 10); str2[2] = 0;
int d = k * i;
TCHAR str3[3]; _itot(d, str3, 10); str3[2] = 0;
TCHAR *st = new TCHAR[25];
for (int j = 0; j < 25; j++) {
st[i] = _T("\0");
st = wcscat(st, str2);
st = wcscat(st, _T("*"));
st = wcscat(st, str1);
st = wcscat(st, _T("="));
st = wcscat(st, str3);
st = wcscat(st, _T("\n"));
PrintMsg(hStdOut, st);
}
}
getch();
system("pause>nul");
return 0;
}
На самом деле с того времени поменяло совсем не много. А проблема тут очевидно в использовании T
макросов вместо использования wchar_t
напрямую. Например
hStdOut = CreateFile(_T("CONOUT$"),
должно быть
hStdOut = ::CreateFileW(L"CONOUT$",
и т.д.
Погуглив, исправил код следующим образом:
#define _CRT_SECURE_NO_WARNINGS
- для совместимости с старыми "небезопасными ф-ями". Для возможности изменения строки нужно писать не TCHAR * pr = _T("Введите множитель: ");
, а TCHAR pr[] = _T("Введите множитель: ");
(суть в [] - теперь можно инициализировать литералом). Также, вместо st[i] = _T("\0");
st[i] = _T('\0');
(символ всё-таки). Новый код:
#define UNICODE
#define _UNICODE
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <tchar.h>
#include <conio.h>
#include <iostream>
using namespace std;
BOOL PrintMsg(HANDLE hOut, LPCTSTR pMsg);
BOOL PrintStrings(HANDLE hOut, ...);
int main(char argc, char ** _targv) {
setlocale(LC_ALL, "");
int k;
HANDLE hStdOut;
hStdOut = CreateFile(_T("CONOUT$"), GENERIC_WRITE, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetConsoleMode(hStdOut, ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_PROCESSED_OUTPUT);
TCHAR pr[] = _T("Введите множитель: ");
PrintMsg(hStdOut, pr);
cin >> k;
TCHAR pr2[] = _T("Таблица умножения:\n");
PrintMsg(hStdOut, CharUpper(pr2));
TCHAR str1[3]; _itot(k, str1, 10); str1[2] = 0;
for (int i = 0; i <= 10; i++) {
TCHAR str2[3]; _itot(i, str2, 10); str2[2] = 0;
int d = k * i;
TCHAR str3[3]; _itot(d, str3, 10); str3[2] = 0;
TCHAR *st = new TCHAR[25];
for (int j = 0; j < 25; j++) {
st[i] = _T('\0');
st = wcscat(st, str2);
st = wcscat(st, _T("*"));
st = wcscat(st, str1);
st = wcscat(st, _T("="));
st = wcscat(st, str3);
st = wcscat(st, _T("\n"));
PrintMsg(hStdOut, st);
}
}
_getch();
system("pause>nul");
return 0;
}
В общем, почти все проблемы решены, осталось лишь решить вопрос с новой ошибкой:
Ошибка LNK2019 ссылка на неразрешенный внешний символ "int __cdecl PrintMsg(void *,wchar_t const *)" (?PrintMsg@@YAHPAXPB_W@Z) в функции _main
Не подскажите, что тут-то не так?
Забыл про следующий листинг, где описание ф-ии PrintMsg:
#define UNICODE
#define _UNICODE
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <tchar.h>
#include <conio.h>
#include <iostream>
using namespace std;
BOOL PrintStrings(HANDLE hOut, ...) {
DWORD MsgLen, Count;
LPCTSTR pMsg;
va_list pMsgList;
va_start(pMsgList, hOut);
while ((pMsg = va_arg(pMsgList, LPCTSTR)) != NULL) {
MsgLen = lstrlen(pMsg);
if (!WriteConsole(hOut, pMsg, MsgLen, &Count, NULL)) return FALSE;
}
return TRUE;
}
BOOL PrintMsg(HANDLE hOut, LPCTSTR pMsg) {
return PrintStrings(hOut, pMsg, NULL);
}
int main(char argc, char ** _targv) {
setlocale(LC_ALL, "");
int k;
HANDLE hStdOut;
hStdOut = CreateFile(_T("CONOUT$"), GENERIC_WRITE, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetConsoleMode(hStdOut, ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_PROCESSED_OUTPUT);
TCHAR pr[] = _T("Введите множитель: ");
PrintMsg(hStdOut, pr);
cin >> k;
TCHAR pr2[] = _T("Таблица умножения:\n");
PrintMsg(hStdOut, CharUpper(pr2));
TCHAR str1[3]; _itot(k, str1, 10); str1[2] = 0;
for (int i = 0; i <= 10; i++) {
TCHAR str2[3]; _itot(i, str2, 10); str2[2] = 0;
int d = k * i;
TCHAR str3[3]; _itot(d, str3, 10); str3[2] = 0;
TCHAR *st = new TCHAR[25];
for (int j = 0; j < 25; j++)
st[j] = _T('\0');
st = wcscat(st, str2);
st = wcscat(st, _T("*"));
st = wcscat(st, str1);
st = wcscat(st, _T("="));
st = wcscat(st, str3);
st = wcscat(st, _T("\n"));
PrintMsg(hStdOut, st);
}
_getch();
system("pause>nul");
return 0;
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Дана строка, состоящая из символов латинского алфавита, разделенных пробелами (одним или несколькими)Определить количество слов, которые...
есть char b[50] = "11 2 6" или он может быть записан char b[50] = "1 23 6"