2011-12-14 10 views
1

ユーザーにコンソールでファイル名/パスの入力を求め、CreateFile()を使用してこのファイルを開こうとしています。現時点では、ハードコードされたファイル名とTEXT()マクロを使用すると、CreateFile()の呼び出しが機能します。ただし、ユーザー入力を渡すと、呼び出しは失敗し、GetLastError()はエラー123または "ファイル名、ディレクトリ名、またはボリュームラベル構文が正しくありません"を返します。以下は関連するコードですが、なぜこれが起こっているのか分かりません。それはハードコードされたファイルパスを動作させるために参考のためにWin32 APIを使用してユーザー指定のファイルを読み取る

LPTSTR dllPath; 
LPDWORD dllPathLength; 
dllPath = (LPTSTR)calloc(MAX_PATH, sizeof(TCHAR)); 
dllPathLength = new DWORD; 
if(ReadConsole(hStdIn, dllPath, MAX_PATH, dllPathLength, NULL)==0) 
{ 
    _tprintf(TEXT("ReadConsole failed with error %d\n"), GetLastError()); 
    return 1; 
} 


_tprintf(TEXT("File path entered: %s\n"), dllPath); 

hDll = CreateFile(dllPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL); 
if (hDll == INVALID_HANDLE_VALUE) 
{ 
    _tprintf(TEXT("CreateFile failed with error %d\n"), GetLastError()); 
    return 1; 
} 

は、私はとのCreateFile()を呼び出し、「TEXT(」:\ log.log C「)」の「たDllPath」パラメータを置き換えます。

ご協力いただければ幸いです。私はまだWindowsスタイルのCプログラミングに慣れようとしていますし、普通のスタイルでもそれほど良いことはありませんでした。

+1

ところで、TCHARマクロや友人を使う理由はまったくありません。Win95は長年にわたり、現在サポートされているWin32 OSはすべてUNICODEです。代わりにWCHAR/wprintf/LPWSTR/L ""を直接使うことができます。また、dllPathLengthの場合、このためにメモリを割り当てる必要はありません。DWORD変数を直接使用するだけです: 'DWORD dwDllPathLength = 0;を宣言し、'&dwDllPathLength'をパラメータとして渡します。 – BrendanMcK

答えて

3

これを試してみてください:

TCHAR dllPath[MAX_PATH+1] = {0}; 
DWORD dllPathLength = 0; 
if(!ReadConsole(hStdIn, dllPath, MAX_PATH, &dllPathLength, NULL)) 
{ 
    _tprintf(TEXT("ReadConsole failed with error %u\n"), GetLastError()); 
    return 1; 
} 

_tprintf(TEXT("File path entered: %s\n"), dllPath); 

hDll = CreateFile(dllPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL); 
if (hDll == INVALID_HANDLE_VALUE) 
{ 
    _tprintf(TEXT("CreateFile failed with error %u\n"), GetLastError()); 
    return 1; 
} 

をそれはまだ動作しない場合は、ReadConsole()はそれを無効にする返されるパスの末尾に改行や他のターミネータを含めていないことを確認してください。そうであれば、CreateFile()に電話する前にそれを取り除く必要があります。

+0

だから、ReadConsole()は結果として得られる文字列の終わりに実際に改行とキャリッジリターン(ASCII値10と13)を含めているように見えますが、これが原因です。これを処理するきれいな方法があれば!あなたの助けをありがとう:) –

+1

清潔な方法があります - 'ReadConsole()'を直接使用しないでください。 'gets()'や 'gets_s()'のような標準的なCランタイム関数を使うか、独自の 'istream :: getline()'メソッドかグローバルな 'std :: getline() '関数(または必要ならば、それらのUnicode equivilents)を呼び出します。これらのアプローチのいずれかが自動的に返されたデータから改行をトリミングします。 –

関連する問題