const — C ++ # определить LPWSTR?

Хорошо, у меня есть проблема в моей программе. Я задавал вопрос об этом раньше, но никто не понимал мою проблему, поэтому на этот раз я пытаюсь по-новому взглянуть на нее.

Если вам интересно, это моя проблема:

Моя программа принимает аргументы в виде char* argv[] и я не могу сделать указатель на то, что на argv[1] с помощью LPWSTR, поскольку это только указывает на const wchar_t* объекты.

Это новое, что я пытаюсь решить мою проблему (я пробовал несколько вещей, но мне нужно знать, как делать то, что я думаю, или, если это возможно)

По сути, моя идея состоит в том, чтобы #define какая-то функция, которая принимает все, что на argv[1] и определяет const wchar_t* с этим значением.

Что-то вроде этого:

#define path       ((const wchar_t*)argv[1])

Я не уверен, что это правильный способ (или даже если это возможно) сделать то, что я хочу сделать …

Если у вас нет лучшего способа решить мою проблему, пожалуйста (пожалуйста), скажите мне, как и помочь мне, я так долго думал об этом!

Объяснение моей программы:

Я делаю программу, которая получает аргументы. Аргументами являются имена дисков, например «F:». Затем он использует функцию CreateFile с буквой диска. Если вы идете Вот , и увидеть первый параметр функции, я думаю, вы поймете, что я имею в виду …. проблема в том, что для меня, чтобы сделать LPWSTR, мне нужен const wchat_t * объект …. я надеюсь, мой вопрос ясен на этот раз, в прошлый раз, люди действительно не поняли, что я пытался сделать.

Независимо, спасибо!
РЕДАКТИРОВАТЬ 1: вот строки решения моей программы (это то, как я должен сделать, чтобы она работала без аргументов) (здесь я использовал фиксированное значение)

int main()
{

HANDLE device;

device = CreateFile(L"\\\\.\\F:",    // Drive to open
GENERIC_READ | GENERIC_WRITE,       // Access mode
FILE_SHARE_READ | FILE_SHARE_WRITE, // Share Mode
NULL,                   // Security Descriptor
OPEN_EXISTING,          // How to create
0,                      // File attributes
NULL);
}

Это с аргументами (не работает)

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

HANDLE device;

device = CreateFile(argv[1],    // Drive to open
GENERIC_READ | GENERIC_WRITE,       // Access mode
FILE_SHARE_READ | FILE_SHARE_WRITE, // Share Mode
NULL,                   // Security Descriptor
OPEN_EXISTING,          // How to create
0,                      // File attributes
NULL);                  // Handle to template
}

^ это показывает, что я пытаюсь сделать

РЕДАКТИРОВАТЬ 2: я изменил CreateFile в CreateFileA и это коды eroor, которые он мне дает (диск D — это USB, это не жесткий диск)
erros

Так что, если я не наберу неправильный способ набрать путь, это всегда дает мне ошибки. Я думаю, что попробуйте другой способ решить проблему, или, если кто-то знает, почему происходят эти ошибки, пожалуйста, сообщите!

0

Решение

РЕДАКТИРОВАТЬ 2: я изменил CreateFile на CreateFileA, и это коды eroor, которые он мне дает (диск D — это USB, а не жесткий диск)

Это совершенно другой вопрос, и не имеет ничего общего с wchar_t,

В твоем первом прорезанном ты прошел "\\\\.\\F:" (AKA \\.\F: как только мы уберем С, спасаясь); во всех ваших попытках из командной строки вы никогда не указывали этот путь, но соответственно:

  • D — поэтому он попытался открыть файл с именем D в текущем каталоге, и он не нашел его (ошибка 2, ака ERROR_FILE_NOT_FOUND);
  • D:\ — корневой каталог, который нельзя открыть с помощью CreateFile (ошибка 3, ака ERROR_PATH_NOT_FOUND),
  • D: — текущий каталог на диске D :, который снова нельзя открыть с помощью CreateFile (ошибка 5, ака ERROR_ACCESS_DENIED);
  • \D: — файл с именем «D:» в корне текущего диска, который нельзя создать, если D: неверное имя файла (ошибка 123, ака ERROR_INVALID_NAME).

Чтобы открыть диск как устройство, вы должен использовать \\.\X: путь (где X буква диска); Вы не можете просто выбросить все, что всплывает в уме, и надеяться, что это сработает. Вызов вашей программы из командной строки "\\.\D:" и это будет работать нормально.

Конечно, если вы хотите, чтобы это было проще для пользователя, вы можете принять только букву диска в командной строке и написать код для создания строки, требуемой для CreateFile основываясь на этом.

if(argc<1) {
printf("Not enough arguments\n");
return 1;
}
const char *drive = argv[1];
char d = drive[0];
// accept both `d` and `d:` as argument for the drive
if(!((d>='a' && d<='z') || (d>='A' && d<='Z')) ||
(drive[1]!=0 && drive[1]!=':') ||
drive[2]!=0) {
printf("Invalid drive specifier: `%s`\n", drive);
return 2;
}
char path[]="\\\\.\\X:";
path[4] = d;
// now you can use path as argument to CreateFileA

Далее следует оригинальный ответ, который все еще действует, но он решает совершенно другую проблему, не связанную с реальной проблемой, с которой сталкивается ОП

Вы не можете сделать LPWSTR указать на char *, особенно не жестоким приведением указателя — приведение указателя просто заставляет компилятор замолчать, это не меняет того факта, на что вы указываете не wchar_t строка. Если вы хотите пройти char * к функции, ожидающей wchar_t * Вы должны выполнить фактическое преобразование указанных данных.

Теперь у вас есть несколько возможных решений:

  • ты можешь использовать _wmain и получите аргументы командной строки непосредственно в виде широких символов;
  • Вы можете преобразовать строки локального кодирования в строки UTF-16 с помощью функции, такой как MultiByteToWideChar; это может быть заключено в функцию, возвращающую std::wstring;
  • вы можете просто вызвать ANSI-версию API и позволить ей справиться с этим; почти все Win32 API имеют версии ANSI и Unicode, с суффиксами A и W (CreateFile это просто макрос, который расширяется до CreateFileA или же CreateFileW в зависимости от _UNICODE макро). Итак, вы можете использовать CreateFileA и передай свою строку как есть.

Последние два решения не являются хорошими, потому что использование строк локальной кодировки в качестве аргументов командной строки не позволяет вашей программе открывать файлы с использованием произвольных символов Юникода. OTOH, используя wchar_t почти везде это ужасно, так как они «заражают» практически каждый уголок обработки вашего приложения. Правильный (IMHO) выход — везде использовать UTF-8 и конвертировать на лету при общении с операционными системами; смотрите здесь для деталей.

7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]