C 语言允许程序获取执行文件时提供的命令行参数,通过 main() 函数中的两个可选参数,分别是 argc(参数个数)和 argv(参数向量)。

  • argc 变量给出程序接收到的命令行参数的数量。这个数量包括程序本身的名称,因此它的值至少为 1。
  • argv 变量是指向一个字符串数组的指针,每个元素包含一个命令行参数。

以下是示例程序:

/* cmdline.c */
#include <stdio.h>

void main( int argc, char *argv[] )
{
    int ctr;
    for( ctr=0; ctr < argc; ctr++ )
    {
        puts( argv[ctr] );
    }
}

如果这个程序从命令行运行:

stooges moe larry curley

输出将是:

stooges
moe
larry
curley

实际上,命令行通常会包含多个参数,其中一些表示选项或开关,通常由前导的 "-""/" 标识。一些开关可能是单独指定的或一起指定的,有些可能接受一个关联的参数。其他参数将是文本字符串,表示数字、文件名或其他数据。

以下示例程序演示了如何解析命令行参数。假设合法的选项字符是 "A""B""C""S",并且可以是大写或小写。"S" 选项后必须跟一个表示参数的字符串。

/* cparse.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main( int argc, char *argv[] )
{
    int m, n,                              /* 循环计数器 */
        l,                                 /* 字符串长度 */
        x,                                 /* 退出代码 */
        ch;                                /* 字符缓冲区 */
    char s[256];                           /* 字符串缓冲区 */

    for( n = 1; n < argc; n++ )            /* 扫描参数 */
    {
        switch( (int)argv[n][0] )           /* 检查选项字符 */
        {
        case '-':
        case '/': x = 0;                   /* 如果为1则退出 */
                  l = strlen( argv[n] );
                  for( m = 1; m < l; ++m ) /* 扫描选项 */
                  {
                      ch = (int)argv[n][m];
                      switch( ch )
                      {
                      case 'a':              /* 合法选项 */
                      case 'A':
                      case 'b':
                      case 'B':
                      case 'c':
                      case 'C':
                      case 'd':
                      case 'D': printf( "Option code = %c\n", ch );
                                break;
                      case 's':              /* 字符串参数 */
                      case 'S': if( m + 1 >= l )
                                {
                                    puts( "Illegal syntax -- no string!" );
                                    exit( 1 );
                                }
                                else
                                {
                                    strcpy( s, &argv[n][m+1] );
                                    printf( "String = %s\n", s );
                                }
                                x = 1;
                                break;
                      default:  printf( "Illegal option code = %c\n", ch );
                                x = 1;      /* 非法选项 */
                                exit( 1 );
                                break;
                      }
                      if( x == 1 )
                      {
                          break;
                      }
                  }
                  break;
        default:  printf( "Text = %s\n", argv[n] ); /* 非选项 -- 文本 */
                  break;
        }
    }
    puts( "DONE!" );
}

作为一个更实际的例子,以下是一个简单的程序,基于前一章的示例,它尝试从命令行读取输入文件和输出文件的名称。如果没有提供文件,它将使用标准输入和标准输出。如果提供了一个文件,它将假设这是输入文件,并打开标准输出。如果提供了两个文件,它将使用这两个文件。这是一个用于简单文件处理程序的有用模板。

/* cpfile.c */
#include <stdio.h>
#include <stdlib.h>
#define MAX 256

void main( unsigned int argc, unsigned char *argv[] )
{
    FILE *src, *dst;
    char b[MAX];

    /* 尝试打开源文件和目标文件 */
    switch (argc)
    {
    case 1:          /* 没有参数,使用标准输入输出 */
        src = stdin;
        dst = stdout;
        break;

    case 2:          /* 一个参数 -- 使用输入文件和标准输出 */
        if ( ( src = fopen( argv[1], "r" )) == NULL )
        {
            puts( "Can't open input file.\n" );
            exit( 0 );
        }
        dst = stdout;
        break;

    case 3:         /* 两个参数 -- 使用输入文件和输出文件 */
        if ( ( src = fopen( argv[1], "r" )) == NULL )
        {
            puts( "Can't open input file.\n" );
            exit( 0 );
        }
        if ( ( dst = fopen( argv[2], "w" )) == NULL )
        {
            puts( "Can't open output file.\n" );
            exit( 0 );
        }
        break;

    default:        /* 参数过多 */
        puts( "Wrong parameters.\n" );
        exit( 0 );
    }

    /* 复制文件内容 */
    while( ( fgets( b, MAX, src ) ) != NULL )
    {
        fputs( b, dst );
    }

    /* 完成,关闭文件 */
    fclose( src );
    fclose( dst );
}
Last modified: Tuesday, 28 January 2025, 12:03 AM