strcmp()的分段错误

if(strcmp(argv[2], NULL) == 0) 

我传递了3个命令行参数,但我也想用上面的语句只用2个命令行参数来运行它。 但是正在显示分段错误错误。

我也尝试过

 if(argc < 3) 

但它也没有用……同样的分段错误……

为什么分段错误?

由于代码if(strcmp(argv[2], NULL) == 0) ,你将NULL作为字符串指针传递给strcmp()函数; 尝试在NULL处进行deference以比较字符代码(例如acsii代码),这会在运行时导致未定义的行为。

您应该使用==将字符串指针与NULL进行比较, if(argv[2] == NULL)

我传递了3个命令行参数,但我也想用上面的语句只用2个命令行参数来运行它。

您可以通过两种方式实现此目的:

  1. 主要语法是:

     int main(int argc, char* argv[]) 

    第一个参数argc是参数计数器,它是传递给进程的参数总数,包括进程名称。

    所以当你没有传递额外的参数时, argc == 1例如./exe

    假设您传递三个参数如下:

     ./exe firstname lastname 

    然后argc == 3 ,看起来你传递了两个参数,但是包含可执行文件名,你实际上是要传递三个参数进行处理。

    所以你可以使用argc值来循环迭代来打印传递的参数(其他可执行文件)

      printf("Process name is: %s", argv[0]); for(i = 1; i < argc; i++ ){ printf("argv[%d] %s\n", argv[i]); } 
  2. 第二种技术是使用第二个参数: argv[]是字符串字符串的NULL终止数组,因此argv[argc]始终等于NULL。 您可以在循环中使用此信息来迭代和处理传递的参数。

    要理解这一点,假设您正在执行以下function:

     ./exe firstname lastname 

    然后argv[0] == ./exe argv[1] == firstnameargv[2] == lastnameargv[3] == NULL ,注意这次argc == 3argv[argc]表示argv[3] == NULL)。

    例如,要打印所有参数,您可以编写如下代码:

      int i = 1; printf("Process name is: %s", argv[0]); while(argv[i]){// terminates when argv[i] == NULL printf("argv[%d] %s\n", argv[i]); i++; } 

您是否注意到argv[0]始终是您的可执行名称! 这意味着无论何时需要打印可执行文件名时,都要在编写代码时使用argv[0]而不是可执行文件的硬代码名称,这样如果重新编译并为可执行文件赋予新名称,则argv[0]始终打印正确的名称。 您应该编写如下代码:

 int main(int argc, char* argv[]){ : :// some other code if(argc < min_number_of_arguments){ fprintf(stderr, "Error: wrong number of arguments passed!\n"); fprintf(stderr, "Usage: %s [first] [second] \n", argv[0]); exit(EXIT_FAILURE); } : :// some other code return EXIT_SUCCESS; } 

首先,您应始终使用strcmp(some_string, "")而不是strcmp(some_string, NULL)来检查字符串是否为空。

但是在你的问题中,你应该测试

 if (argc < 4) 

那是因为可执行文件本身也在数组argv 。 考虑你正在调用像./a.out param0 param1这样的东西,然后argc将是3argv[0]="./a.out"argv[1]="param0"argv[2]="param1"

编辑:

另外,永远不要直接测试if(strcmp(argv[2], NULL) == 0) 。 始终先测试argc 。 由于没有受让人在argv[argc+n]存储的值为n >= 0

您不能使用strcmp()来比较NULL 。 两个参数都不能为空。 在这种情况下,无论如何都没有意义。 如果参数不存在,则argc将<3,如果它以某种方式为空,则它将为零长度。 永远不会。