Как вернуть строку переменного размера из функции? - PullRequest
0 голосов
/ 25 августа 2011

Мне нужен рабочий код для функции, которая будет возвращать случайную строку со случайной длиной.

То, что я хочу сделать, было бы лучше описано следующим кодом.

char *getRandomString()
{
    char word[random-length];
    // ...instructions that will fill word with random characters.
    return word;
}
void main()
{
    char *string = getRandomString();
    printf("Random string is: %s\n", string);
}

Для этого мне категорически запрещено использовать любые другие файлы, кроме stdio.h .Изменить: Этот проект будет адаптирован для компиляции для PIC Microcontroller, поэтому я не могу использовать malloc () или такие вещи.Причина, по которой я здесь использую stdio.h , заключается в том, что я могу проверить вывод, используя GCC .

В настоящее время этот код выдает эту ошибку.«Предупреждение: функция возвращает адрес локальной переменной [включено по умолчанию]»

Затем я подумал, что это может сработать .-

char *getRandomString(char *string)
{
    char word[random-length];
    // ...instructions that will fill word with random characters.
    string = word;
    return string;
}
void main()
{
    char *string = getRandomString(string);
    printf("Random string is: %s\n", string);
}

Но он печатает только кучу бессмысленных символов.

Ответы [ 5 ]

4 голосов
/ 25 августа 2011

Есть три распространенных способа сделать это.

  1. Пусть вызывающая сторона передает указатель на (первый элемент) массива, в который должны быть сохранены данные, вдольс параметром длины.Если возвращаемая строка больше передаваемой длины, это ошибка;вам нужно решить, как с этим бороться.(Вы можете усечь результат или вернуть нулевой указатель. В любом случае вызывающая сторона должна иметь с ним дело.)

  2. Вернуть указатель на вновь выделенный объектчто делает ответственность вызывающего абонента звонить free, когда закончите.Вероятно, вернет нулевой указатель, если malloc() не удастся (это всегда возможно, и вы должны всегда проверить это).Поскольку malloc и free объявлены в <stdlib.h>, это не соответствует вашим (искусственным) требованиям.

  3. Возвращает указатель на (первый элемент) a статический массив.Это позволяет избежать ошибки возврата указателя на локально размещенный объект, но у него есть свои недостатки.Это означает, что более поздние вызовы будут перекрывать исходный результат, и он налагает фиксированный максимальный размер.

Нет, если это идеальное решение.

2 голосов
/ 25 августа 2011

Указывает на бессмысленные символы, потому что вы возвращаете локальный адрес.char word[random-length]; определено локально для char *getRandomString(char *string)

Динамически распределить строку с помощью malloc, заполнить строку и вернуть возвращенный адрес с помощью malloc.Этот возвращенный адрес выделяется из кучи и будет выделяться до тех пор, пока вы не освободите его вручную (или программа не прекратит работу).

char *getRandomString(void)
{
    char *word;
    word = malloc (sizeof (random_length));
    // ...instructions that will fill word with random characters.
    return word;
}

После того, как вы закончили с выделенной строкой, не забудьте освободитьstring.

Или можно сделать что-то другое, если вы не можете использовать malloc, который определяет локальную строку в getRandomString как static, что делает статически объявленный срок жизни массива таким же, как и программа..

char *getRandomString(void)
{
    static char word[LENGTH];
    // ...instructions that will fill word with random characters.
    return word;
}

Или просто сделать char word[128]; глобальным.

0 голосов
/ 25 августа 2011

Если вам не разрешено использовать malloc, вам придется объявить массив, который может иметь максимально возможный размер в области видимости файла, и заполнить его случайными символами.

#define MAX_RANDOM_STRING_LENGTH  1024
char RandomStringArray[MAX_RANDOM_STRING_LENGTH];

char *getRandomString(size_t length)
{
  if( length > ( MAX_RANDOM_STRING_LENGTH - 1 ) ) {
    return NULL; //or handle this condition some other way

  } else {
    // fill 'length' bytes in RandomStringArray with random characters.
    RandomStringArray[length] = '\0';
    return &RandomStringArray[0];

  }
}

int main()
{
    char *string = getRandomString(100);
    printf("Random string is: %s\n", string);

    return 0;
}
0 голосов
/ 25 августа 2011

Как я понимаю, malloc не вариант.

Напишите пару функций: а) получить случайное целое число (длина строки) и б) случайный символ.

Затем используйте их для построения случайной строки.

Например:

//pseudocode
static char random_string[MAX_STRING_LEN];
char *getRandomString()
{
    unsigned int r = random_number();

    for (i=0;i<r;i++){
        random_string[i] = random_char();
    }

    random_string[r-1] = '\0';
}
0 голосов
/ 25 августа 2011

Оба ваших примера возвращают указатели на локальные переменные - это, как правило, нет-нет.Вы не сможете создать память для вашего вызывающего абонента без malloc(), который не определен в stdio.h, поэтому я думаю, что ваш единственный вариант - сделать word статическим или глобальным, если вы не можете объявить этов main() и передайте указатель на функцию случайных строк для заполнения. Как вы генерируете случайные числа только с функциями в stdio.h?

...