strcmp()的分段错误

an5*_*56k 3 c segmentation-fault argv

if(strcmp(argv[2], NULL) == 0)
Run Code Online (Sandbox Code Playgroud)

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

我也尝试过

if(argc < 3)
Run Code Online (Sandbox Code Playgroud)

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

Gri*_*han 8

为什么分段错误?

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

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

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

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

  1. 主要语法是:

    int main(int argc, char* argv[])
    
    Run Code Online (Sandbox Code Playgroud)

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

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

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

    ./exe firstname lastname    
    
    Run Code Online (Sandbox Code Playgroud)

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

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

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

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

    ./exe firstname lastname    
    
    Run Code Online (Sandbox Code Playgroud)

    然后argv[0] == ./exe,argv[1] == firstnameargv[2] == lastnameargv[3] == NULL,注意这个时候argc == 3(argv[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++;
      }
    
    Run Code Online (Sandbox Code Playgroud)

你注意到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;
}
Run Code Online (Sandbox Code Playgroud)