Retornando string da function C

Eu não uso C há mais de 3 anos, estou muito enferrujado em muitas coisas.

Eu sei que isso pode parecer estúpido, mas não posso retornar uma string de uma function no momento. Por favor, assuma que: Eu não posso usar string.h para isso.

Aqui está o meu código:

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

Eu posso capturar a string (com minha function getStr ), mas não consigo mostrá-la corretamente (recebo lixo).

Ajuda é apreciada.

Aloque a string na pilha no lado do chamador e passe para a sua function:

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

Ou torne a string estática em getStr :

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

Ou aloque a string no heap:

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

Isto não é bom. Você está retornando um ponteiro para uma variável automática (com escopo), que será destruída quando a function retornar. O ponteiro ficará apontando para uma variável destruída, o que quase certamente produzirá resultados “estranhos” (comportamento indefinido).

Você deve estar alocando a string com malloc (por exemplo, char *rtnPtr = malloc(length) ), depois char *rtnPtr = malloc(length) free a mais tarde no main .

Você está alocando sua seqüência na pilha e, em seguida, retornando um ponteiro para ele. Quando sua function retorna, qualquer alocação de pilha se torna inválida; o ponteiro agora aponta para uma região na pilha que provavelmente será sobrescrita na próxima vez que uma function for chamada.

Para fazer o que você está tentando fazer, você precisa seguir um destes procedimentos:

  1. Aloque memory no heap usando malloc ou similar e, em seguida, retorne esse ponteiro. O chamador precisará, então, chamar free quando for feito com a memory.
  2. Alocar a seqüência na pilha na function de chamada (aquele que estará usando a seqüência de caracteres) e passar um ponteiro para a function para colocar a seqüência de caracteres em. Durante toda a chamada para a function de chamada, os dados em sua pilha são válidos; é só quando você retorna que o espaço alocado da pilha é usado por outra coisa.

Seu ponteiro está apontando para a variável local da function. Então, assim que você retornar da function, a memory será desalocada. Você tem que atribuir memory na pilha, a fim de usá-lo em outras funções.

Em vez disso, char *rtnPtr = word;

faça isso char *rtnPtr = malloc(length);

De modo que está disponível na function principal. Depois é usado para liberar a memory.

word está na pilha e sai do escopo assim que getStr() retorna. Você está invocando um comportamento indefinido.

Ainda mais fácil: retornar um ponteiro para uma string que foi malloc com 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; } 

Eu me deparei com esta discussão enquanto trabalhava no meu entendimento sobre o Cython. Minha extensão para a pergunta original pode ser útil para outras pessoas que trabalham na interface do C / Cython. Portanto, esta é a extensão da pergunta original: como faço para retornar uma string de uma function C, tornando-a disponível para o Cython e, assim, para o Python?

Para aqueles que não estão familiarizados com ele, o Cython permite que você digite estaticamente o código Python que precisa acelerar. Portanto, o processo é, divirta-se escrevendo Python :), encontre um pouco lento em algum lugar, faça o perfil dele, pare uma function ou duas e cifreie-as. Uau. Perto da velocidade C (compila para C) Fixo. Yay. O outro uso é importar funções ou bibliotecas C para o Python, como feito aqui.

Isso imprimirá uma string e retornará a mesma ou outra string para o Python. Existem 3 arquivos, o arquivo c c_hello.c, o arquivo cython sayhello.pyx e o arquivo de instalação do cython sayhello.pyx. Quando eles são compilados usando python setup.py build_ext --inplace eles geram um arquivo de biblioteca compartilhada que pode ser importado para python ou ipython e a function sayhello.hello é executada.

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 )