繁体   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