从C函数返回string

三年多来我一直没有用过C,很多东西我都生锈了。

我知道这可能看起来很愚蠢,但我现在不能从函数返回一个string。 请假定:我不能使用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; } 

我可以捕获string(用我的getStr函数),但我不能让它正确显示(我得到垃圾)。

帮助表示赞赏。

要么在调用者端分配栈上的string,并将其传递给你的函数:

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

或者让getStr的string为静态:

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

或者在堆上分配string:

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

不是很好。 您正在返回一个指向自动(范围)variables的指针,该函数在函数返回时将被销毁。 指针将被指向一个被破坏的variables,这几乎肯定会产生“奇怪的”结果(未定义的行为)。

你应该用malloc分配string(例如char *rtnPtr = malloc(length) ),然后在main free它。

您正在堆栈中分配您的string,然后返回一个指针。 当你的函数返回时,任何堆栈分配都会失效。 现在指针指向堆栈上的一个区域,下次调用某个函数时可能会覆盖该区域。

为了做你想做的事情,你需要做以下的一件事:

  1. 使用malloc或类似方法在堆上分配内存,然后返回该指针。 当存储器完成后,调用者将需要free呼叫。
  2. 在调用函数(将使用string的函数)中的堆栈上分配string,并将指针传递给该函数以放入string。 在调用函数的整个调用过程中,堆栈中的数据是有效的; 它只有一次你返回的那个堆栈分配的空间被其他东西所使用。

word在堆栈上并在getStr()返回时超出范围。 您正在调用未定义的行为。

你的指针指向函数的局部variables。 所以只要你从函数返回,内存就会被释放。 您必须在堆上分配内存才能在其他函数中使用它。

char *rtnPtr = word;

做这个char *rtnPtr = malloc(length);

这样它在主要function中可用。 使用后释放内存。

更容易:返回一个指向已被malloc'd strdup的string的指针。

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

我在了解Cython的同时,遇到了这个线程。 我对原始问题的扩展可能对在C / Cython接口工作的其他人有用。 所以这是原始问题的扩展:我如何从C函数返回一个string,使它可用于Cython和Python?

对于那些不熟悉它的人,Cython允许你静态地input你需要加速的Python代码。 所以这个过程是,喜欢编写Python :),在某个地方find它有点慢,分析它,产生一个或两个函数,并将它们集成到一起。 哇。 接近C速度(编译为C)固定。 好极了。 另一个用途是将C函数或库导入到Python中,就像这里所做的那样。

这将打印一个string并将相同或另一个string返回给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 )