Usando getopt en C con argumentos no opcionales

Estoy haciendo un pequeño progtwig en C que trata con muchos argumentos de la línea de comandos, así que decidí usar getopt para ordenarlos.

Sin embargo, quiero que dos argumentos no opcionales (archivos de origen y destino) sean obligatorios, por lo que debe tenerlos como argumentos al llamar al progtwig, incluso si no hay indicadores u otros argumentos.

Aquí hay una versión simplificada de lo que tengo que manejar los argumentos con banderas:

while ((c = getopt(argc, argv, "i:d:btw:h:s:")) != -1) { switch (c) { case 'i': { i = (int)atol(optarg); } case 'd': { d = (int)atol(optarg); } case 'b': buf = 1; break; case 't': time = 1; break; case 'w': w = (int)atol(optarg); break; case 'h': h = (int)atol(optarg); break; case 's': s = (int)atol(optarg); break; default: break; } } 

¿Cómo edito esto para que los argumentos sin opción también se manejen?

También quiero poder tener las no opciones antes o después de las opciones, entonces, ¿cómo se manejaría eso?

getopt establece la variable optind para indicar la posición del siguiente argumento.

Agregue un código similar a este después del bucle de opciones:

 if (argv[optind] == NULL || argv[optind + 1] == NULL) { printf("Mandatory argument(s) missing\n"); exit(1); } 

Editar:

Si desea permitir opciones después de argumentos regulares, puede hacer algo similar a esto:

 while (optind < argc) { if ((c = getopt(argc, argv, "i:d:btw:h:s:")) != -1) { // Option argument switch (c) { case 'i': { i = (int)atol(optarg); } case 'd': { d = (int)atol(optarg); } case 'b': buf = 1; break; case 't': time = 1; break; case 'w': w = (int)atol(optarg); break; case 'h': h = (int)atol(optarg); break; case 's': s = (int)atol(optarg); break; default: break; } else { // Regular argument  optind++; // Skip to the next argument } } 

Realmente se puede encontrar un buen ejemplo aquí: GNU Libc El código:

 #include  #include  #include  #include  int main (int argc, char **argv) { int aflag = 0; int bflag = 0; char *cvalue = NULL; int index; int c; opterr = 0; while ((c = getopt (argc, argv, "abc:")) != -1) switch (c) { case 'a': aflag = 1; break; case 'b': bflag = 1; break; case 'c': cvalue = optarg; break; case '?': if (optopt == 'c') fprintf (stderr, "Option -%c requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return 1; default: abort (); } printf ("aflag = %d, bflag = %d, cvalue = %s\n", aflag, bflag, cvalue); for (index = optind; index < argc; index++) printf ("Non-option argument %s\n", argv[index]); return 0; } 

Permite tener opciones antes y después de los argumentos. He comstackdo y ejecutado el ejemplo de prueba:

 $ ./a.out aa ff bb -a -ctestparam hello aflag = 1, bflag = 0, cvalue = testparam Non-option argument aa Non-option argument ff Non-option argument bb Non-option argument hello