Как мне вернуть массив строк из рекурсивной функции? - PullRequest
0 голосов
/ 29 июня 2010

Как мне вернуть массив строк из рекурсивной функции?

Например ::

char ** jumble( char *jumbStr)//reccurring function
{
   char *finalJumble[100];

   ...code goes here...call jumble again..code goes here

   return finalJumble;
} 

Спасибо заранее.

Ответы [ 4 ]

6 голосов
/ 29 июня 2010

В C вы не можете вернуть строку из функции.Вы можете только вернуть указатель на строку.Следовательно, вы должны передать строку, которую вы хотите вернуть, в качестве параметра функции (НЕ использовать глобальные переменные или локальные статические переменные функции) следующим образом:

char *func(char *string, size_t stringSize) {
    /* Fill the string as wanted */
    return string;
}

Если вы хотите вернуть массивСтроки, это еще сложнее, прежде всего, если размер массива меняется.Лучшим ИМХО может быть возвращение всех строк в одной строке, объединение строк в буфере строк и пустая строка в качестве маркера для последней строки.

char *string = "foo\0bar\0foobar\0";

Ваша текущая реализация неверна, так какон возвращает указатель на переменные, которые определены в локальной области видимости функции.

(Если вы действительно используете C ++, верните std::vector<std::string>.)

2 голосов
/ 29 июня 2010

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

Если вы все еще хотите продолжить этот подход, передайте по ссылке (&) массив символов этой функции и прекратите повторение, как только вы достигнете желаемой конечной точки. После того, как вы закончите, у вас должны быть нужные символы 'jumbled'.

2 голосов
/ 29 июня 2010

Вы не: -)

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

Таким образом, вы сгенерируете массив jumble вне метода jumble:

void jumble_client( char *jumbStr)
    char *finalJumble[100];

     jumble(finalJuble, jumbStr);

     ... use finalJumble ...
} 

void jumble( char **jumble, char *jumbStr)
{
   ...code goes here...call jumble again..code goes here
}

И, конечно, вы будете использовать типы данных stl вместо массивов символов и, возможно, захотите проверить, было бы разумно написать класс jumble, в котором данные finalJumble являются членами.Но все это немного дальше по дороге.Тем не менее, как только вы решите исходную проблему, попробуйте узнать, как это сделать, чтобы узнать больше.

1 голос
/ 29 июня 2010

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

typedef std::vector<std::string> TJumbleVector;

int jumble(char* jumbStr, TJumbleVector& finalJumble) //reccurring function 
{
    int err = 0;; // error checking

     ...code goes here...call jumble again..code goes here
     // finalJumble.push_back(aGivenString);

     return err; 
}  

Если вы хотите сделать это в C, вы можете отслеживать количество строк, выполнять malloc при последнем рекурсивном вызове и заполнять массив после каждого рекурсивного вызова. Следует помнить, что вызывающая сторона должна освободить выделенную память. Другой вариант заключается в том, что вызывающая сторона делает первый вызов, чтобы увидеть, сколько места ему нужно для массива, затем выполняет malloc и вызов jumble:

char** jumble(char* jumbStr)
{
    return recursiveJumble(jumbStr, 0);
}

char** recursiveJumble(char* jumbStr, unsigned int numberOfElements)
{
    char** ret = NULL;
    if (/*baseCase*/)
    {
        ret = (char**) malloc(numberOfElements * sizeof(char*));
    }
    else
    {
        ret = jumble(/*restOfJumbStr*/, numberOfElements+1);
        ret[numberOfElements] = /*aGivenString*/;
    }
    return ret;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...