2017-06-16 3 views
0

私のプログラムに問題があります。私はそれについて前に質問しましたが、誰も私の問題を本当に理解していなかったので、今度は新しいアプローチを試しています。C++ #define LPWSTR?

私のプログラムはchar* argv[]の形で引数をとり、そして、argv[1]LPWSTRを使用して上にあるものは何でもへのポインタを作成する問題が発生したイムにそれが唯一のポイントになったのは:あなたは好奇心旺盛であれば

が、これは私の問題ですconst wchar_t*オブジェクト。

これは私の問題を解決しようと新しいものイムですが(私は複数のものを試してみたが、私は何イム思考、またはその可能な場合の対処方法を知っておく必要があります)

Basiclyが、私の考えがあります#defineには、argv[1]にある何らかの種類の関数があり、その値でconst wchar_t*が定義されています。このような

何か:

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

イムわからないことが正しい方法である(あるいはこれが可能であっても)私はやりたいし...

あなたはアニー良くしている場合私の問題を解決する方法は、(どうか)私に方法を教えて、私を助けてください、私はこれについて本当に長い時間を考えてきました!

私のプログラムの説明:

イム引数をrecievesプログラムを作ります。引数はドライブの名前です(例: "F:")。次に、ドライブ文字と共に関数CreateFileを使用します。もしあなたがhereに行き、関数の最初のパラメータを見ると、私はあなたが何を意味するのか見ることができると思います....問題は、LPWSTRを作るためには、const wchat_t *オブジェクトが必要です。私の質問が今回はっきりしていることを願って、最後に人々は本当に何をしようとしているのか理解しませんでした。

感謝! EDIT 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); 
} 

これは(doesnの引数である」(私はここでは固定値を使用しました)トン作業は)

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 
} 

^これはイム

EDIT 2をやろうとしているものを示しています。私はCreateFileACreateFileを変更し、これはそれが私に与えeroorコードです(ドライブDは、USBは、あるそのハードドライブではない) erros

私はパスを入力する間違った方法を入力しない限り、それは常に私にerrosを与えます。私は病気が別の方法で問題を解決しようとしていると思う、あるいは誰かがなぜthoesのエラーが起こっているのか知っていたら、教えてください!

+0

あなたのプログラムのコードを投稿できますか?私はそれがあなたの主な機能の最初の数行だと思います。 – kennyzx

+0

@kennyzx確かに、編集 – jeyejow

+0

多分マクロは最高の方法ではありませんhttps://stackoverflow.com/questions/14041453/why-are-preprocessor-macros-evil-and-what-are-the-alternatives – ldgorman

答えて

7

EDIT 2:私はCreateFileAへのCreateFileを変更し、これはeroorコードである、それは私を与える(ドライブDは、USB、そのないハードドライブである)

これは完全に異なっています質問は、wchar_tとは関係ありません。

あなたの最初のスナップでは、"\\\\.\\F:"(AKA \\.\F:はCエスケープを削除した後)を渡しました。

  • D - それは、現在のディレクトリにDという名前のファイルを開こうとしましたが、それは、(エラー2がそれを見つけられませんでした:あなたは、それぞれこのパスを提供しませんが、決して、コマンドラインからすべての試行で別名ERROR_FILE_NOT_FOUND);
  • D:\
  • - CreateFile(別名エラー3、ERROR_PATH_NOT_FOUND)で開くことができないルートディレクトリ、
  • D: - 再度CreateFile(エラー5で開くことができないドライブD:上のカレントディレクトリ、別名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 

以下は、実際の問題のOPとは無関係の、まだ有効ですが、それは全く別の問題に対処し、元の答えは、あなたがLPWSTRポイントを作ることができない

を経験しているましたchar *に、特にでないポインタを残酷にキャストすることによって - ポインタをキャストするだけで、コンパイラがシャットダウンしますが、あなたが何をポイントしているかng atはではなく、 a wchar_t文字列です。 wchar_t *が必要な関数にchar *を渡したい場合は、指し示すデータの実際の変換を実行する必要があります。今

、あなたはいくつかの可能な解決策があります:あなたは_wmainを使用して直接ワイド文字として、コマンドライン引数を受け取ることができ

  • を。
  • MultiByteToWideCharなどの関数を使用して、ローカルエンコーディング文字列をUTF-16文字列に変換できます。これは、std::wstringを返す関数にカプセル化することができます。
  • あなたはちょうどANSIバージョンのAPIを呼び出してそれに対処することができます。ほぼすべてのWin32 APIは、A及びW接尾辞ANSIとUnicodeバージョン、(CreateFileマクロ_UNICODEに応じCreateFileAまたはCreateFileWに展開だけマクロである)の両方を有します。したがって、CreateFileAを使用して、そのまま文字列を渡すことができます。

ローカルコード化文字列をコマンドライン引数として使用すると、プログラムが任意のUnicode文字を使用してファイルを開くことができなくなるため、最後の2つの解決法はあまり役に立ちません。 OTOHの場合、wchar_tをほとんどどこでも使っているため、アプリケーションのほとんどの文字列処理コーナーに「感染」するため、かなり恐ろしいことです。正しい(IMHO)方法は、どこでもUTF-8を使用して、オペレーティングシステムと話すときにオンザフライで変換することです。 see here for details

+0

私は理解しません私はこれを行う場合= int _wmain(int argc、char * argv [])、それでも引数を保存していないchar *ですか? – jeyejow

+0

いいえ、 '_wmain'は別の宣言(' int _wmain(int argc、wchar_t * argv []) ')を持っているためです。しかし、ここにある問題はこれとは関係ありません。私の答えを編集させてください。 –

+0

してください、私は本当に私の問題を理解したい。 – jeyejow