Windows程式內如何取得Command line參數?
可以使用GetCommandLine()來取得Command line參數,下面一個簡易範例。
int argc;
char** argv = CommandLineToArgv(GetCommandLine(), argc);
string img_path = argc>1?argv[1]:" ";
delete[] argv[0]; // 使用完要刪除
delete[] argv; // 使用完要刪除
因為微軟的SDK只有提供寬字元版的CommandLineToArgvW,所以我花了點時間寫一般字元的版本,這個處理並不包含參數中間內有雙引號的情況,不過參數的頭尾是雙引號有做,所以某些參數可能跟系統的不太一樣。
我使用的是狀態機的作法,因為這樣比較容易發想與處理,用一張圖就可以搞定想法與實作。
第一次掃描將空白符號與不必要的符號都設為'\0',並獲得參數數目 argc。
第二次掃描將資料設定到argv中,因為第一次掃描已經將不必要的符號都設為'\0'所以可以用簡便的方法處理argv
char** CommandLineToArgv(char* sys_cmd, int& argc)
{
int curr_state;
char **argv, **argv_itr;
char *cmd_itr, *loc;
int cmd_len = strlen(sys_cmd);
char *cmd = new char[cmd_len+1];
char *cmd_end = cmd+cmd_len;
strncpy(cmd, sys_cmd, cmd_len);
cmd[cmd_len] = '\0';
argc = 0;
curr_state = 0;
for (cmd_itr=cmd ; cmd_itr!=cmd_end ; ++cmd_itr)
{
switch(curr_state)
{
case 0:
if (isspace(*cmd_itr))
*cmd_itr = '\0';
else
{
if (*cmd_itr=='"')
{
*cmd_itr = '\0';
curr_state = 2;
}
else
curr_state = 1;
argc++;
}
break;
case 1: // character
if (isspace(*cmd_itr))
{
*cmd_itr = '\0';
curr_state = 0;
}
break;
case 2: // quater
if (*cmd_itr =='"')
{
*cmd_itr = '\0';
loc = cmd_itr;
curr_state = 3;
}
break;
case 3:
if (isspace(*cmd_itr))
{
*cmd_itr = '\0';
curr_state = 0;
}
else
{
*loc = *cmd_itr; // move character
*cmd_itr = '\0';
}
break;
}// end switch
}
argv = new char*[argc];
// find the first non-zero char location, and move the data to the head
for (cmd_itr=cmd ; !*cmd_itr && cmd_itr!=cmd_end ; ++cmd_itr)
; // empty
memmove(cmd, cmd_itr, cmd_len+1-(cmd_itr-cmd));
curr_state = 0;
argv_itr = argv;
for (cmd_itr=cmd ; cmd_itr!=cmd_end ; ++cmd_itr)
{
switch(curr_state)
{
case 0:
if (*cmd_itr)
{
*argv_itr++ = cmd_itr;
curr_state = 1;
}
break;
case 1:
if (*cmd_itr == '\0')
curr_state = 0;
break;
}
}
return argv;
}
留言