Подтвердить что ты не робот

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

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

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

Вот мой код:

#include <ncurses.h>

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), но я не могу заставить ее отображаться правильно (я получаю мусор).

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

4b9b3361

Ответ 1

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

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;
}

Ответ 2

char word[length];
char *rtnPtr = word;
...
return rtnPtr;

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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

Ответ 5

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

Ответ 6

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

#include <ncurses.h>

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;
}

Ответ 7

Я столкнулся с этой нитью, работая над моим пониманием Китона. Мое расширение исходного вопроса может быть полезным для других, работающих на интерфейсе 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 <stdio.h>

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
)