【问题标题】:How do you use getopt() with non option arguments如何使用带有非选项参数的 getopt()
【发布时间】:2014-03-22 13:08:04
【问题描述】:

我正在尝试将 getopt() 用于需要“e”或“d”选项来选择加密或解密的程序,然后需要一个密钥用于任一操作。我的问题是我不确定如何使用 getopt() 处理密钥。在这一点上,我已经阅读了 man getopt() 的大部分内容和许多其他文章。我目前收到浮点错误和核心转储,并收到警告消息:

cypher.c:在函数“main”中: cypher.c:14:3:警告:从不兼容的指针类型传递“getopt”的参数 2 [默认启用] /usr/include/getopt.h:152:12:注意:预期为“char * const*”,但参数的类型为“char *” cypher.c:28:13: 警告:赋值从没有强制转换的指针生成整数 [默认启用]

以下是实际代码,感谢您的帮助。

include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

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

  int e,x; 
  int i=0;      
  int c=fgetc(stdin);
  //  int n=strlen(key);
  int encrypt;

  while((x = getopt (argc, argv, "ed")) != -1){
    switch (x){
    case 'e':
      encrypt=1;
      break;
    case 'd':
      encrypt=0;
      break;
    default:
      fputs("you broke it\n",stderr);
      exit(1);
    }
  }
    char key[100];
    key[100]= argv[optind++];
    int n = strlen(key);

    if(encrypt == 1){
      while(c != EOF){
         c= fgetc(stdin);
         e=(c - 32 + key[i % n]) % 95 +32;
         fputc( e, stdout);
         i++;
      }
    }
    else{
      while( e != EOF){
         c = fgetc(stdin);
         c=(e - 32 -key[i % n] +3 * 95) % 95 +32;
         fputc(c, stdout);
         i++;
      }
    }
  exit (0);
 }

【问题讨论】:

  • @hek2mgl,如果您是新人,手册页很烂,所以投反对票,也很烂...
  • 我在这里没有人投票。我认为这个手册页确实很有帮助,因为它带有示例和很好的解释。它不,试一试。我也读过,不错。我已经明确发布了man 3 ...,因为我想表明只输入man getopt 会为您提供具有相同功能的shell 程序的手册页,这是不同的事情,并且与C 函数的行为也不同。快乐的选项解析! :)

标签: c bash stdin getopt


【解决方案1】:

getopt(3) 有一个很好的例子:

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

int
main(int argc, char *argv[])
{
    int flags, opt;
    int nsecs, tfnd;

   nsecs = 0;
    tfnd = 0;
    flags = 0;
    while ((opt = getopt(argc, argv, "nt:")) != -1) {
        switch (opt) {
        case 'n':
            flags = 1;
            break;
        case 't':
            nsecs = atoi(optarg);
            tfnd = 1;
            break;
        default: /* '?' */
            fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
                    argv[0]);
            exit(EXIT_FAILURE);
        }
    }

   printf("flags=%d; tfnd=%d; optind=%d\n", flags, tfnd, optind);

   if (optind >= argc) {
        fprintf(stderr, "Expected argument after options\n");
        exit(EXIT_FAILURE);
    }

   printf("name argument = %s\n", argv[optind]);

   /* Other code omitted */

   exit(EXIT_SUCCESS);
}

【讨论】:

    【解决方案2】:

    大多数Linux新手甚至不知道man,Windows中没有man
    此外,系统管理员可能未安装该软件包。如果您可以在您的机器上安装软件包,请安装该软件包:

    sudo apt get install manpages-dev # on debian based systems
    

    这是一个有用的资源,您可以找到所有可能的手册页列表:

     dpkg -L manpages-dev
    

    这就是你要找的东西:

    $ dpkg -L manpages-dev| grep getop
    /usr/share/man/man3/getopt.3.gz
    /usr/share/man/man3/getopt_long_only.3.gz
    /usr/share/man/man3/getopt_long.3.gz
    

    这是一个带有明文的好例子,除了手册页(倾向于简洁)......

    http://linuxprograms.wordpress.com/2012/06/22/c-getopt-example/

    【讨论】:

    • 是的man 3 ... 真的很有帮助!初学者应该知道。好答案!
    • 顺便说一句:试试“apropos getopt”
    【解决方案3】:

    通常您希望将选项处理分为两个步骤:

    1. 收集所有选项并对它们进行任何预处理(例如检查它们的有效性)并根据需要将它们存储在变量或结构中。
    2. 实际上是根据遇到的全套选项采取行动。

    所以基本上你可能想要设置一个全局变量(例如opt_mode = ENCRYPTopt_mode = DECRYPT 或类似的东西),并根据需要存储密钥。然后在所有选项处理完成后,根据opt_mode变量实际进行加密或解密。

    【讨论】:

    • 谢谢,这几乎很有意义。你让我免于用头撞墙数小时。
    猜你喜欢
    • 2021-06-24
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 2019-07-29
    • 2013-12-22
    • 1970-01-01
    相关资源
    最近更新 更多