Как я могу захватить строку из функции в C, которая возвращает строку? - PullRequest
0 голосов
/ 13 сентября 2011

Я новичок в C и создал следующий код, но при запуске программа вылетает.Зачем?Как мне остановить его сбой?

char *get()
{
    char *n;
    printf("\n user name : ");
    scanf("%s", &n);
    return n;
}

int main()
{
    char *c = get();

    printf("%s", c);

    return 0;
}

Ответы [ 3 ]

4 голосов
/ 13 сентября 2011

В C типично, что родительский объект обрабатывает выделение памяти, поскольку нет сборщика мусора, который нужно очистить после себя, поэтому он должен делать это в любом случае:

void get(char *n)
{
    printf("\n user name : ");
    scanf("%s", n);
}

int main()
{
    char c[200];
    get(c);
    printf("%s", c);

    return 0;
}

http://ideone.com/Tw347

3 голосов
/ 13 сентября 2011

scanf читает символы из stdin и сохраняет их в памяти, на которую указывает n. Вы не инициализировали n, чтобы указывать на что-либо, поэтому scanf, вероятно, пытается сохранить ваш ввод в каком-то произвольном месте в памяти. Вам повезло, что он разбился, а не вел себя так, как будто работал правильно.

Возвращение строки из функции C более сложно, чем вы могли бы ожидать.

Существует (как минимум) три общих подхода:

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

  2. Объявите массив static внутри функции и верните указатель на него. (Вы не можете вернуть указатель на нестатический локальный массив, так как массив перестает существовать, когда функция возвращается.) Проблемы: при множественных вызовах используется одно и то же пространство памяти (особенно проблематичное при наличии потоков) и выделенное размер фиксированный.

  3. Выделите результат внутри функции, используя malloc(). Это требует от вызывающего абонента free() результата.

Рекомендуемое чтение: comp.lang.c FAQ . В частности, вопрос 7.5b - это почти прямой ответ на ваш вопрос (и он бы сэкономил мне немного времени, если бы я понял это раньше). (Обычно я не ссылаюсь на отдельные вопросы, потому что мне нравится побуждать людей к просмотру.)

РЕДАКТИРОВАТЬ: Кроме того, scanf с неквалифицированным форматом "%s" по своей сути небезопасны. Он будет пытаться сохранить сколько угодно символов, введенных в массив; нет способа избежать переполнения буфера (скажем, если ваша кошка сидит на клавиатуре). @Artefacto упомянул эту проблему в ссылке в комментарии.

1 голос
/ 13 сентября 2011

Прежде всего вы должны выделить память для вашей строки

вы можете сделать это динамически, используя malloc;

например с размером 200 :

#include <stdlib.h>

char (*n)[200] = malloc(sizeof *n);

не забудьте освободить указатель с помощью

free(n);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...