Restituendo una stringa dalla funzione C.

Non uso C da più di 3 anni, sono piuttosto arrugginito su un sacco di cose.

So che questo può sembrare stupido ma al momento non posso restituire una stringa da una funzione. Supponiamo che: Non posso usare string.h per questo.

Ecco il mio codice:

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

Posso catturare la stringa (con la mia funzione getStr ) ma non riesco a visualizzarla correttamente (ottengo spazzatura).

L’aiuto è apprezzato

    Alloca la stringa nello stack sul lato del chiamante e passa alla tua funzione:

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

    O rendere la stringa statica in getStr :

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

    O allocare la stringa sull’heap:

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

    Questo non è buono. Si sta restituendo un puntatore a una variabile automatica (con ambito), che verrà distrutta al termine della funzione. Il puntatore verrà lasciato puntato su una variabile distrutta, che produrrà quasi certamente risultati “strani” (comportamento non definito).

    Si dovrebbe allocare la stringa con malloc (ad es. char *rtnPtr = malloc(length) ), quindi free in seguito in main .

    Stai allineando la tua stringa allo stack e quindi restituisci un puntatore ad esso. Quando la funzione ritorna, eventuali allocazioni di stack non sono più valide; il puntatore ora punta a una regione nello stack che rischia di essere sovrascritta la prossima volta che viene chiamata una funzione.

    Per fare ciò che stai cercando di fare, devi eseguire una delle seguenti azioni:

    1. Assegna memoria all’heap usando malloc o simili, quindi restituisci quel puntatore. Il chiamante dovrà quindi chiamare free quando è fatto con la memoria.
    2. Assegna la stringa sullo stack nella funzione di chiamata (quella che utilizzerà la stringa) e passa un puntatore alla funzione per inserire la stringa. Durante l’intera chiamata alla funzione chiamante, i dati sul suo stack sono validi; è solo una volta che si restituisce che lo spazio allocato dello stack viene utilizzato da qualcos’altro.

    Il puntatore punta alla variabile locale della funzione. Quindi, non appena si ritorna dalla funzione, la memoria viene deallocata. Devi assegnare memoria su heap per usarlo in altre funzioni.

    Invece char *rtnPtr = word;

    fai questo char *rtnPtr = malloc(length);

    In modo che sia disponibile nella funzione principale. Dopo viene utilizzato gratuitamente la memoria.

    word è in pila e esce dal campo di applicazione non appena getStr() restituisce. Stai invocando un comportamento indefinito.

    Ancora più semplice: restituire un puntatore a una stringa che è stata malloc’d con 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; } 

    Mi sono imbattuto in questo thread mentre lavoravo sulla mia comprensione di Cython. La mia estensione alla domanda originale potrebbe essere utile agli altri che lavorano all’interfaccia C / Cython. Quindi questa è l’estensione della domanda originale: come posso restituire una stringa da una funzione C, rendendola disponibile a Cython e quindi a Python?

    Per coloro che non hanno familiarità con esso, Cython consente di digitare staticamente il codice Python che è necessario accelerare. Quindi il processo è, divertiti a scrivere Python :), trovarlo un po ‘lento da qualche parte, tracciarlo, eliminarne una o due e renderle cythonize. Wow. Vicino alla velocità C (si compila a C) Risolto. Sìì. L’altro uso è l’importazione di funzioni o librerie C in Python come fatto qui.

    Questo stamperà una stringa e restituirà la stessa o un’altra stringa a Python. Ci sono 3 file, il file c c_hello.c, il file cython sayhello.pyx e il file di installazione di cython sayhello.pyx. Quando sono compilati usando python setup.py build_ext --inplace generano un file di libreria condivisa che può essere importato in python o ipython e la funzione sayhello.hello run.

    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 )