Возврат строки из функции C

Я не использовал C более 3 лет, я довольно ржавый по многим вещам.

Я знаю, что это может показаться глупым, но я не могу вернуть строку из функции на данный момент. Предположим, что: я не могу использовать string.h для этого.

Вот мой код:

 #include  char * getStr(int length) { char word[length]; for (int i = 0; i < length; i++) { word[i] = getch(); } word[i] = '\0'; return word; } int main() { char wordd[10]; initscr(); *wordd = getStr(10); printw("The string is:\n"); printw("%s\n",*wordd); getch(); endwin(); return 0; } 

Я могу захватить строку (с моей функцией getStr ), но я не могу заставить ее отображаться правильно (я получаю мусор).

Помощь приветствуется.

Либо выделите строку в стеке на стороне вызывающего абонента, либо передайте ее функции:

 void getStr(char *wordd, int length) { ... } int main(void) { char wordd[10 + 1]; getStr(wordd, sizeof(wordd) - 1); ... } 

Или сделайте статическую строку в getStr :

 char *getStr(void) { static char wordd[10 + 1]; ... return wordd; } 

Или выделите строку в куче:

 char *getStr(int length) { char *wordd = malloc(length + 1); ... return wordd; } 
 char word[length]; char *rtnPtr = word; ... return rtnPtr; 

Это не хорошо. Вы возвращаете указатель на автоматическую (облачную) переменную, которая будет уничтожена при возврате функции. Указатель будет указывать на уничтоженную переменную, которая почти наверняка произведет «странные» результаты (неопределенное поведение).

Вы должны выделить строку с помощью malloc (например, char *rtnPtr = malloc(length) ), а затем free ее позже в main .

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

Чтобы сделать то, что вы пытаетесь сделать, вам необходимо выполнить одно из следующих действий:

  1. Выделите память в куче, используя malloc или аналогичный, затем верните этот указатель. Затем вызывающему абоненту необходимо позвонить free когда это будет сделано с памятью.
  2. Выделите строку в стеке в вызывающей функции (той, которая будет использовать строку), и передайте указатель на функцию для ввода строки. Во время всего вызова вызывающей функции данные в его стеке действительны; его только после того, как вы вернете, что выделенное стекное пространство будет использовано чем-то другим.

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

Вместо char *rtnPtr = word;

сделайте это char *rtnPtr = malloc(length);

Так что он доступен в основной функции. После его использования освободите память.

word находится в стеке и выходит за frameworks, как только getStr() возвращается. Вы вызываете неопределенное поведение.

Еще проще: верните указатель на строку, которая была malloc’d с помощью strdup .

 #include  char * getStr(int length) { char word[length]; for (int i = 0; i < length; i++) { word[i] = getch(); } word[i] = '\0'; return strdup(&word[0]); } int main() { char wordd[10]; initscr(); *wordd = getStr(10); printw("The string is:\n"); printw("%s\n",*wordd); getch(); endwin(); return 0; } 

Я наткнулся на эту тему, работая над моим пониманием Китона. Мое расширение исходного вопроса может быть полезным для других, работающих на интерфейсе C / Cython. Итак, это расширение исходного вопроса: как вернуть строку из функции C, сделав ее доступной для Cython & таким образом Python?

Для тех, кто не знаком с этим, Cython позволяет вам статически вводить код Python, который вам нужно ускорить. Таким образом, процесс – это удовольствие от написания Python :), где-то его где-то немного замедлить, профилировать, отложить функцию или два и cythonize. Вау. Близко к скорости C (она компилируется на C) Исправлено. Ура. Другое использование – импорт C-функций или библиотек в Python, как это делается здесь.

Это напечатает строку и вернет ту же или другую строку в Python. Есть 3 файла, c файл c_hello.c, файл cython sayhello.pyx и файл настройки cython sayhello.pyx. Когда они скомпилированы с использованием python setup.py build_ext --inplace они создают файл общей библиотеки, который может быть импортирован в python или ipython, а функция sayhello.hello запускается.

c_hello.c

 #include  char *c_hello() { char *mystr = "Hello World!\n"; return mystr; // return "this string"; // alterative } 

sayhello.pyx

 cdef extern from "c_hello.c": cdef char* c_hello() def hello(): return c_hello() 

setup.py

 from setuptools import setup from setuptools.extension import Extension from Cython.Distutils import build_ext from Cython.Build import cythonize ext_modules = cythonize([Extension("sayhello", ["sayhello.pyx"])]) setup( name = 'Hello world app', cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules ) 
  • Число регулярных выражений от 1 до 100
  • Конкатенация строк и String Builder. Представление
  • Строковый вывод: формат или concat в C #?
  • Получить индекс шаблона в строке с использованием регулярного выражения
  • Как объединить две строки в C?
  • История за названием «String»
  • Что такое пул строк Java и как он отличается от нового String («s»)?
  • Обратный String C ++ с использованием массива char
  • Проверьте, содержит ли строка другую строку
  • Что делает сравнение ссылок (==) для некоторых строк в Java?
  • LINQ: Строка строки Entity содержит любой массив строк
  • Давайте будем гением компьютера.