簡體   English   中英

更改命令行參數

[英]changing command line arguments

我正在寫一個C程序。 它從命令行獲取參數。 我想在代碼中更改命令行參數。 由於它們被定義為“ const char *”,因此我無法使用“ strcpy”,“ memcpy”,...來更改它們。此外,您知道,我不能僅將其類型從“ const char *”更改為“ char *” ”。 有什么辦法可以改變它們嗎?

提前非常感謝您。

最好的問候,沙迪。

根據C99§5.1.2.2.1/ 1, main的簽名為

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

所以,你允許刪除的const 只要不導致緩沖區溢出通過strcpy ING在比原來的論點長字符串,或試圖比原先通過安裝更多的論據。

其他人基本上都應該創建副本。

不可以,您不能修改它們。 但是,沒有規則禁止將它們復制到新緩沖區並改為使用它們。

這可能不合時宜,但是您既不能使用strcpy()也不能使用memcpy()進行任何更改。 后綴“ cpy”是復制的簡稱(毫不奇怪)。

關於更改argv指針,您當然可以更改指針,但是為什么呢? 如果您希望命令行參數不是給定的參數,請忽略它們,並使用您喜歡的任何值。 還要注意,argv是一個參數,因此對於main()是局部的; 如果在其他地方需要它,則必須將其作為參數傳遞,或將其另存為全局變量。

如果將const char *更改為main函數的char *沒關系。

您只需要關心的一件事就是strcpy的緩沖區溢出。

根據ELF規范(請參閱圖3-31堆棧布局), http://refspecs.linuxbase.org/elf/abi386-4.pdf ,函數參數區域后跟環境值區域。

argv是指向每個參數的指針數組,而environ也是指向每個環境的指針數組var = value字符串。 因此布局如下所示。

argv[0]  --> 1st parameter
argv[1]  --> 2nd parameter
argv[2]  --> 3rd parameter
...
NULL
--------------------------------------- memory boundary between param and env
environ[0] --> 1st env_var=env_value
environ[1] --> 2nd env_var=env_value
environ[2] --> 3rd env_var=env_value
...
NULL

因此,如果將很長的字符串復制到argv [0],則它可能會超出param和env之間的邊界。 在這種情況下,必須將argv和環境存儲區移至另一個堆空間,如下所示。 我從Postgresql開源代碼中提取了以下示例代碼。 ps_status.c)

char ** new_environ;
char ** new_argv;
char ** org_argv;
int     i;

new_argv = (char **) malloc((argc + 1) * sizeof(char *));
for (i = 0; i < argc; i++)
    new_argv[i] = strdup(argv[i]);
new_argv[argc] = NULL;
org_argv = argv;
argv = new_argv;

new_environ = (char **) malloc((i + 1) * sizeof(char *));
for (i = 0; environ[i] != NULL; i++)
    new_environ[i] = strdup(environ[i]);
new_environ[i] = NULL;
environ = new_environ;

然后,您可以使用getopt,getenv等。它們將從新分配的內存區域讀取值。 另外,如果更改原始參數(org_argv [0]),則可以在ps命令中操作進程的輸出名稱。 (也位於htop實用工具的頂部),請參見下文。

$> ps -ef | grep my_proc
  dplee 10855 1 0 7월28 pts/2 00:00:16 my_proc i can manipulate this name

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM