2016-04-18 9 views
1

私はlpCmdLineがどのように動作するかを理解しようとしていますが、やや直感的です。lpCmdLineはどのように格納されていますか?

元々は、コマンド文字列全体へのポインタに過ぎないと思っていましたが、lpCmdLineの表示にはゴミが直接表示されるため、このコードではそうではありません。

#include <Windows.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <stdarg.h> 

void alertf(const char *fmt, ...) 
{ 
    char buf[80]; 
    va_list args; 
    va_start(args, fmt); 
    sprintf_s(buf, fmt, args); 
    va_end(args); 

    MessageBox((HWND)0, buf, "Message Box", MB_OK | MB_ICONINFORMATION); 
} 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    alertf("lpCmdLine: '%s'.", lpCmdLine); 

    return 0; 
} 

lpCmdLineは内部でどのように格納されていますか?その引数が可変引数であるため、

ソリューション

私alertfはvsprintf_sの代わりsprintf_sを使用する必要があります。

この1つの変更は、lpCmdLineが実際に私が思ったように、コマンドライン全体のc文字列であることを確認します。

+0

注:ANSI形式のコマンドラインのみです(常に)。 'GetCommandLineW()' API関数を使ってUnicodeのコマンドラインを取得することができます。 –

+0

@Dmitry、StackOverflowで、あなたの質問のタイトルに "ANSWERED"を追加する必要はありませんし、元の質問に解決策を提供する必要はありません。 – dreamlax

+0

@dreamlax申し訳ありません。 – Dmitry

答えて

5

lpCmdLineは実際にはコマンド文字列への単純なポインタです。

#include <windows.h> 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    MessageBox(NULL, lpCmdLine, "DEBUG", MB_OK); 

    return 0; 
} 

問題は、あなたのsprintf_s呼び出しがあなたはそれがないと思う何をしていませんあなたのalertf機能、であるように思われます。あなたが実際に起因するva_listの存在のために、ここでvsprintf_sを使用する必要があります。

void alertf(const char *fmt, ...) 
{ 
    char buf[80]; 
    va_list args; 
    va_start(args, fmt); 
    vsprintf_s(buf, fmt, args); 
    va_end(args); 

    MessageBox((HWND)0, buf, "Message Box", MB_OK | MB_ICONINFORMATION); 
} 

コードはその後完璧に動作します。

+0

私は指を横切っていました。私の全く無害なalertfは、バッファオーバーフローを引き起こす以外の何か間違ったことをしませんでした...私は今、vsprintfが何をするのか知っていますね。ありがとう! – Dmitry

関連する問題