簡體   English   中英

Argc / Argv C問題

[英]Argc/Argv C Problems

如果我有以下代碼:

main(int argc, char *argv[]){
 char serveradd[20];
 strcpy(serveradd, argv[1]);
 int port = atoi(argv[2]);
 printf("%s %d \n", serveradd, port);

將打印命令行的前兩個參數。 但是,如果我這樣做:

 char serveradd[20];
 strcpy(serveradd, argv[1]);
 int port = atoi(argv[2]);
 char versionnum[1]; 
 strcpy(versionnum, argv[3]);
 printf("%s %d %s \n", serveradd, port, versionnum);`

第一個參數(serveradd)不會輸出到屏幕上,也沒有存儲。...為什么會發生這種情況,我該如何解決? 謝謝!

char versionnum[1];  
strcpy(versionnum, argv[3]); 

大膽的猜測,但是您正在用這些行粉碎堆棧。 使versionnum更大; 就目前而言,它只能安全​​地容納空字符串。

您可能正在用

char versionnum[1]; 
strcpy(versionnum, argv[3]);

假設任何非空的以NULL結尾的字符串的長度都將> 1個字符。

永遠不要使用直接的strcpy(); 使用strncpy()代替(注意-1為空終止符保留空間):

char serveradd[20] = { 0 };
strncpy(serveradd, argv[1], sizeof(serveradd) - 1);
int port = atoi(argv[2]);
char versionnum[2] = { 0 }; 
strcpy(versionnum, argv[3], sizeof(versionnum) - 1);
printf("%s %d %s \n", serveradd, port, versionnum);

使用strcpy而不使用要復制的字符串的strlen來測試長度,以確保它適合目標緩沖區是一個非常糟糕的主意。 您應該使用strncpy ,它經過了長度檢查並且不會超出目標緩沖區。

您不能將字符串存儲在長度為1的char數組中,因為空終止符需要一個字符,因此您可以存儲的只是空字符。 幾乎可以保證您正在溢出緩沖區。

我認為上面的答案解決了您的問題,但是在將來調試時,請嘗試在內存分配方面大方一些。 如果您認為需要5個元素,則將其創建為10,然后如果您想為空終止符騰出空間,則將其更改為5或6。 另外,如果您發現自己分配了一個長度為1的數組,請停止並詢問原因。 如果您有一個元素,只需使用一個普通變量。

每當我在argc和argv上遇到問題時,我首先想到的就是將它們打印出來,以查看是否有我認為的應有的東西。

它以您描述的方式為我工作。 我的猜測是您超出了其中一個字符串的字符數限制。 我會使用strncpy而不是strcpy。

嘗試strdup()

一種替代方法是使用strdup()在堆上分配內存,以免緩沖區溢出。 在您的情況下,由於變量在程序的整個生命周期中都將一直存在,所以還不錯,或者您可以在上次使用變量后立即使用free()釋放內存。 確保之后不要使用變量! 下面是一些示例代碼。


#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main(int argc, char *argv[])
{
      char *serveradd  = NULL;
      int   port;
      char *versionnum = NULL;

      if (argc != 4)
      {
            printf("Usage: %s SERVERADD PORT VERSIONNUM\n", argv[0]);
            exit(126);
      }

      serveradd  = strdup(argv[1]);
      port       = atoi(argv[2]);
      versionnum = strdup(argv[3]);

      if ((serveradd == NULL) || (versionnum == NULL))
      {
            perror("Could not allocate command line arguments");
            exit(125);
      }

      printf("%s %d %s \n", serveradd, port, versionnum);

      free(serveradd);
      free(versionnum);
      serveradd  = NULL;
      versionnum = NULL;
      exit(0);
}

暫無
暫無

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

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