2015-05-12 3 views
0

У меня есть простой typedef (typedef int set [4]) и его создания. У меня есть функция, которая получает 3 из этого typedef как параметры.отправка параметров функции в соответствии с вводом

Теперь я хочу, чтобы функция вызывалась с параметрами в соответствии с вводом. Например, если вход A, D, R (предположим, что все они созданы), функция будет вызываться как func (A, D, R).

Я попытался использовать swich для соответствия символу, а затем отправить подходящий параметр, но он становится слишком грязным, я тоже пробовал что-то другое, но я не мог связать вход и имя объекта.

Я пишу его в C кстати. Любая помощь была бы оценена

+2

Не могли бы вы предоставить кому-то свой код? –

+0

Если я правильно понимаю, вы хотите сделать что-то вроде: 'sscanf ("% c% c% c ", & c0, & c1, &c2); if (c0 == 'A' && c1 == 'D' && c2 == 'R ') func (A, D, R); '? – mtijanic

ответ

0

Похоже, вы хотите передать параметры по имени. Предполагая, что это так, на ум приходят два подхода.

Если имена набора действительно имена односимвольных как A, D, R и т.д., можно построить массив указателей set, индексированных по характеру:

set *sets[128]; // will result in a lot of unused sets, but 
       // indexing is fast and dead easy 

sets['A'] = &A; 
sets['D'] = &D; 
sets['R'] = &R; 
... 
char s1, s2, s3; 
scanf(" %c %c %c", &s1, &s2, &s3);  // Note a complete lack of error checking 
func(*sets[s1], *sets[s2], *sets[s3]); // You *will* want to validate your inputs 

Если вы не хотите тратить столь много места, вы можете сделать что-то вроде

set *sets[26]; // just uppercase letters 

int base = 'A'; 
sets['A'-base] = &A; 
sets['D'-base] = &D; 
sets['R'-base] = &R; 
... 
scanf(" %c %c %c", &s1, &s2, &s3);     // Again, absolutely no error checking 
func(*sets[s1-base], *sets[s2-base], *sets[s3-base]); // You have been warned 

Это предполагает, что вы используете кодировку, в которой все заглавные буквы являются последовательными (ASCII или UTF-8).

Если вы время смарт-код обезьяны и используя значимые имена для наборов, вы можете использовать таблицу поиска, индексированный по характеру строки, что-то вроде следующего:

set foo, bar, bletch...; 

struct lut_entry { 
    char *name; 
    set *data; 
}; 

struct lut_entry lut[] = { 
    {"foo", &foo}, 
    {"bar", &bar}, 
    {"bletch", &bletch}, 
    ... 
    { NULL, NULL } // sentinel value 
}; 

You то может искать эту таблицу для каждого входа:

set *lookup(const char *name, struct lut_entry *lut) 
{ 
    struct lut_entry *cur = lut; 
    while (cur->name && strcmp(cur->name, name)) 
    cur++; 
    return cur->data; 
} 

который вы хотите позвонить, как что-то вроде:

scanf("%s %s %s", name1, name2, name3); 

set *s1 = lookup(name1, lut); 
set *s2 = lookup(name2, lut); 
set *s3 = lookup(name3, lut); 

if (s1 && s2 && s3) 
    func(*s1, *s2, *s3); // note dereference operations! 
else 
    // one or more of name1, name2, and name3 are invalid 
    // handle as appropriate 

В зависимости от того, сколько комплектов вы управляете, и насколько важна скорость для этого приложения, вам может потребоваться изучить нечто более сложное, чем поиск неупорядоченного линейного массива, но это не стоит усилий, если это меньше, чем дюжина или около того.

Почему я не просто передал имена func и попросил ли он выполнить весь поиск?Вы абсолютно можете это сделать, но это значит, что func должно будет делиться состоянием со своим вызывающим абонентом через глобальные переменные, которые я стараюсь избегать, когда это возможно, и это означает, что funcвсегда должен выполнить поиск, хотите ли вы этого или нет , Лучше иметь func получить наборы as-is и заставить вызывающую функцию выполнять поиск, так как вызывающая функция знает, ведется ли она путем ввода пользователем.

+0

yey это сработало :) спасибо за ответ так быстро и так подробно, вы, ребята, самые лучшие! – Ahdriam

1

Если я правильно понял вопрос, у вас есть символы, которые вы хотите перевести на переменные с этим именем .. Это 'A', чтобы стать set A?

Подвижный с этим предположением, вот способ сделать это:

#include <assert.h> 
set func(set x, set y, set z); 

// Global definitions for all set variables. 
struct sets { 
    set A; 
    set B; 
    set C; 
    ... 
    set Z;  
} allSets; 

set callFuncForParams(char c1, char c2, char c3) 
{ 
    set *x, *y, *z; 

    // Make sure the input is legal 
    assert(c1 >= 'A' && c1 <= 'Z'); 
    assert(c2 >= 'A' && c2 <= 'Z'); 
    assert(c3 >= 'A' && c3 <= 'Z'); 

    x = (set *)&allSets + c1 - 'A'; 
    y = (set *)&allSets + c2 - 'A'; 
    z = (set *)&allSets + c3 - 'A'; 

    return func(*x, *y, *z); 
} 

Другим подход, особенно полезно, если вы не имеете все буквы в качестве переменных, чтобы сделать массив struct { char c; set s; }, и затем перейдите через этот массив, чтобы найти свою переменную. Вы можете использовать макросы и оператор # для генерации этого массива.

Смежные вопросы