2

我正在做一个小程序,并意识到我需要用户以正确的顺序输入他的选项,这样我的程序才能正确地完成他的工作,但我认为这是一种应该避免的“错误”,所以我尝试了使程序“顺序独立”工作,但这不起作用,所以我决定找到一个函数,该函数按我选择的顺序执行 optarg 解析选项,但令我惊讶的是,我找不到任何,所以我决定写我的getopt排序函数...问题是,这个工作有一个特定的函数吗?(我写了所有这些代码都是徒劳的:()。如果有一个函数,请告诉我。并且,如果一个函数存在与否,你们可以看看我写的那段代码.. . 提前谢谢。 Obs.: 我想知道是否存在用于该任务的 C 函数。

代码在https://github.com/paolocarrara/getopt_ordering

但这里也是(两个文件):

/*file _getopt.h (first file)*/

#include <stdlib.h>
char **ordering (int *, char **, char *); 

/*file ordering.c (second file)*/

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

#define TRUE    1
#define FALSE   0

int get_line_size (char *line) {
return strlen (line);
}

int verify_if_is_option (char *argv) {

if (argv != NULL) {
    if (argv[0] == '-')
        return TRUE;
    else 
        return FALSE;
}
else
    return FALSE;
}

int problem_counter (int argc, char **argv) {

int i;
int number_of_problens;

for (i = 1, number_of_problens = 0; i < argc; i++)
    if (verify_if_is_option (argv[i]) == TRUE)
        if (get_line_size (argv[i]) > 2)
            number_of_problens++;

return number_of_problens;

}

char **malloc_argv (int argc, char **argv, int t_problens) {

char **new;
int i;

new = malloc ((argc+t_problens)*sizeof(char*));
for (i = 0; i < argc; i++) 
    new[i] = argv[i];
for (; i < argc + t_problens; i++)
    new[i] = NULL;
return new;
}

char *get_problematic_line (int argc, char **argv) {

int i;
char *line = NULL;

for (i = 1; i < argc; i++)
    if (verify_if_is_option (argv[i]) == TRUE)
        if (get_line_size (argv[i]) > 2)
            line = argv[i];
return line;
}

char *get_argument (char *line) {

char *argument;
int i;
argument = malloc ((strlen(line)-1)*sizeof(char));

for (i = 2; i < strlen(line); i++)
    argument[i-2] = line[i];
argument[i-2] = '\0';

return argument;
}

char **push_down (int argc, char **argv, int i) {

for (; argc > i+1; argc--)
    argv[argc-1] = argv[argc-2];
return argv;
}

char **push_one_line_down_from_here (char *line, int argc, char **argv) {

int i;
for (i = 1; i < argc; i++) 
    if (argv[i] == line){
        argv = push_down (argc, argv, i);
        i = argc;
    }
return argv;
}

char **insert_argument_below_this_line (char *line, char *argument, char **argv) {

int i;

for (i = 1; line != argv[i]; i++);
argv[i+1] = argument;
return argv;
}

void remove_argument_from_problematic_line (char *line) {

line[2] = '\0';
}

char **malloc_and_divide (int *argc, char **argv) {

int t_problens;
char *line;
char *argument;

t_problens = problem_counter (*argc, argv);

argv = malloc_argv (*argc, argv, t_problens);

(*argc) +=t_problens;

for (;t_problens > 0; t_problens--) {
    line = get_problematic_line (*argc, argv);
    argument = get_argument (line);
    argv = push_one_line_down_from_here (line, *argc, argv);
    argv = insert_argument_below_this_line (line, argument, argv);
    remove_argument_from_problematic_line(line);
}

return argv;
}

char *litteral_to_dinamic (char *literal) {
int i;
char *dinamic = malloc ((strlen(literal)+1)*sizeof(char));
for (i = 0; i < strlen(literal); i++) dinamic[i] = literal[i];
dinamic[i] = '\0';
return dinamic;
}


char get_desired_option (char *optstring) {
char option;
option = optstring[0];
return option;
}

void remove_option_used (char *optstring) {

int i;

for (i = 1; i <= strlen(optstring); i++)
    optstring[i-1] = optstring[i];
if (optstring[0] == ':')
    remove_option_used (optstring);
}

int is_in_argv (int argc, char **argv, char option) {

int i;

for (i = 1; i < argc; i++)
    if (argv[i][0] == '-' && argv[i][1] == option)
        return TRUE;
return FALSE;
}

int option_have_argument (char **argv, int position) {

if (argv[position+1][0] == '-')
    return TRUE;
else
    return FALSE;
}

int both_have_argument (int argc, char **argv, int position, int i) {

if(i < argc-1){
    if((argv[position+1][0] != '-') && (argv[i+1][0] != '-'))
        return TRUE;
    else 
        return FALSE;
}
else 
    return FALSE;
}

void change_both_arguments (int argc, char **argv, int position, int i) {

char *aux;

aux = argv[position+1];
argv[position+1] = argv[i+1];
argv[i+1] = aux;
}

int first_have_argument (int argc, char **argv, int position) {

if (position < argc-1)
    if (argv[position+1][0] != '-')
        return TRUE;
return FALSE;
}

void change_first_argument (int argc, char **argv, int position, int i) {

char *aux;

aux = argv[position+1];
for (position++; position < i; position++)
    argv[position] = argv[position+1];
argv[i] = aux;

}

int second_have_argument (int argc, char **argv, int i) {

if (i < argc-1)
    if (argv[i+1][0] != '-')
        return TRUE;
return FALSE;
}

void change_second_argument (int argc, char **argv, int position, int i) {

char *aux;
int j;

aux = argv[i+1];
for (j=i+1; j > position; j--)
    argv[j] = argv[j-1];
argv[position+1] = aux;

}

int verify_arguments (int argc, char **argv, int position, int i) {

if (both_have_argument (argc, argv, position, i) == TRUE) {
    change_both_arguments (argc, argv, position, i);
    return position+2;
}
else if (first_have_argument (argc, argv, position) == TRUE) {
    change_first_argument (argc, argv, position, i);
    return position+1;
}
else if (second_have_argument (argc, argv, i) == TRUE) {
    change_second_argument (argc, argv, position, i);
    return position+2;
}
else 
    return position+1;
}


int change_option_position (int argc, char **argv, char option, int position) {

int i;
char *aux;

for (i = 1; i < argc; i++)
    if (argv[i][0] == '-' && argv[i][1] == option) {
        aux = argv[position];
        argv[position] = argv[i];
        argv[i] = aux;
        position = verify_arguments (argc, argv, position, i);
    }
return position;
}

char **organize (int argc, char **argv, char *optstring) {

int position = 1;
char option;

optstring = litteral_to_dinamic (optstring);

while (optstring[0] != '\0') {
    option = get_desired_option (optstring);
    remove_option_used (optstring);
    if ((is_in_argv(argc, argv, option)) ==  TRUE)
        position = change_option_position (argc, argv, option, position);

}

return argv;
}

char **ordering (int *argc, char **argv, char *optstring) {

int i;

argv = malloc_and_divide (argc, argv);

argv = organize (*argc, argv, optstring);

return argv;
}
4

1 回答 1

0

You are correct, there are no functions that will do what you describe. However, why don't you just declare a bitmap and use getopt only to set the values in the bitmap? After that's done, you can then check the bitmap and process the options in whatever order you please. Consider the following example, assuming an arbitrary option 'b' needed to be processed before an arbitrary option 'a'.

#define OPTIONS = "ab"
#define flaga = 0x0001; /* corresponds to a */
#define flagb = 0x0002; /* corresponds to b */

unsigned int flags = 0; /* the bitmap */
char ch = '\0' /* the switch char */

while ((ch = getopt(argc, argv, OPTIONS)) != -1) 
{
    switch (ch) {
    case 'a':       /* set flag a */
        flags |= flaga;
        break;
    case 'b':
        flags |= flagb;
        break;
}

if((flags & flagb) == flagb) 
{
    //process flag b
}
if((flags & flaga) == flaga)
{
    //process flag a
}
于 2014-11-06T03:55:25.600 回答