Pagina 1 di 3
[RISOLTO][C]return di una stringa
Inviato: mar 26 feb 2008, 20:24
da boh
Scrivere un sottoprogramma che ricevute in ingresso due stringhe (e nessun altro parametro) ne crea una nuova costituita dalla concatenazione delle due ricevute in ingresso e la restituisce al chiamante.
Ora come da titolo, il problema è il return di questa stramaledetta nuova stringa!
Nella funzione ho anche creato un puntatore a char, e l'ho assegnato alla nuova stringa facendo returnare quello, ma la stringa non ce l'ho poi nel main.
Come faccio?
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 20:48
da absinthe
eh? non ho mica capito sai! cosa intendi: hai creato un puntatore _dentro_ la funzione di concatenazione (una funzione creata da te? strcat no?) che punta ad una stringa? come la hai allocata la stringa? e poi restituisci una variabile con riferimenti strettamente locali nel main? così restituisci l'indirizzo della stringa ma non è detto che la tringa persista, anzi! mi sa che non funziona così! posta un pò di codice!
M
PS: ma che è un esercizio di scuola e chiedi numi su slacky ?

Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 20:50
da robbybby
C puro:
Codice: Seleziona tutto
/* assicurarsi che szSum abbia spazio almeno per iMaxLen + 1 caratteri */
void concat(const char *cszStr0, const char *cszStr1, char *szSum, int iMaxLen)
{
assert(cszStr0);
assert(cszStr1);
assert(szSum);
assert(iMaxLen > 0);
strncpy(szSum,
cszStr0,
iMaxLen);
szSum[iMaxLen] = '\0';
strncat(szSum,
cszStr1,
iMaxLen - strlen(szSum));
/* non e' necessario assicurarsi che l'ultimo carattere sia il NULL, perche' ci
pensa la strncat (cosa che non fa la strncpy */
}
C++
Codice: Seleziona tutto
//dovrebbe bastare
string concat(const string &cstr0, const string &*cstr1)
{
assert(&cstr0 != 0);
assert(&cstr1 != 0);
return cstr0 + cstr1;
}
//pero' io preferisco una cosa tipo quella in C liscio
void concat(const string &cstr0, const string &*cstr1, string *pstrSum)
{
assert(pstrSum);
*pstrSum = cstr0;
*pstrSum += cstr1;
}
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 20:52
da boh
absinthe ha scritto: così restituisci l'indirizzo della stringa ma non è detto che la tringa persista, anzi! mi sa che non funziona così! posta un pò di codice!
Esatto era quello che pensavo!
E allora come ovviare a questo problema?
Un po' di codice:
Codice: Seleziona tutto
char * miafunz(char str1[], char str2[])
{
char str3[N+N+1]; //N è la dimensione delle due stringhe nel main
strcat(str3, str1);
strcat(str3, str2);
return //??
}
E non so cosa returnare? Più chiaro? =)
EDIT: @robbyrobby: grazie per la risposta, ma io non posso passare altri parametri oltre le due stringhe.
E poi devo far returnare qualcosa, quindi una funzione void non mi va bene

Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 20:57
da robbybby
Non si puo' fare (in realta' si potrebbe, come suggerisco piu' sotto, ma e' un modo che non mi piace per niente), come ti ha spiegato absinthe.
L'unico modo e' qualcosa tipo quello che ti ho postato io. Oppure con una stringa globale, ma nel mondo reale andresti incostro a gravi problemi di manutenibilita' del sw

.
Oppure in C++, li' si puo', sempre come ti ho postato io, grazie all'operator=, overloaded in std::string (mi rifiuto categoricamente di tradurre il termine in italiano!

) e ai copy constructor

.
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:01
da boh
Se devo essere sincero immaginavo non si potesse.
Però da come interpreto io il testo parrebbe invece di si!
Anch'io avrei passato una terza stringa alla funzione...
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:06
da robbybby
boh ha scritto:Se devo essere sincero immaginavo non si potesse.
Però da come interpreto io il testo parrebbe invece di si!
Anch'io avrei passato una terza stringa alla funzione...
In realta' un modo c'e', un po' pericoloso, ma c'e'. In genere non lo si usa nei programmi veri, ma didatticamente puo' essere valido.
Pero' te lo devi trovare da solo.
Ti do' solo un suggerimento: malloc()

Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:08
da Blizzard
[anticipato da robbybby]
ciao ragà,
forse sparo una cavolata... [CENSURA]
[/anticipato da robbybby]
[edit]
effettivamente è giusto (come dice robbybby) che trovi la soluzione da solo.... per questo l'ho rimossa... non so se si può fare... se no la rimetto
sorry
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:13
da robbybby
@Blizzard
Si', ma volevo che la trovasse da se', la soluzione.
Come ho detto prima, la vedo una soluzione valida solo a scopo didattico.
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:15
da boh
Ok, sembra funzionare, posto il codice:
Codice: Seleziona tutto
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 30
char * concatena(char [], char []);
int main()
{
char str1[N+1], str2[N+1];
char *ptr;
scanf("%s %s", str1, str2);
ptr = concatena(str1, str2);
printf("\n%s", ptr);
return 0;
}
char * concatena(char str1[], char str2[])
{
char *p;
p = (char *)malloc((N+N)*sizeof(char));
strcat(p, str1);
strcat(p, str2);
return p;
}
Grazie per i consigli
Ma a questo punto avrei una domanda: perchè lo spazio che ho appena allocato nella funzione non sparisce?
Non è anche quello locale?
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:30
da Blizzard
no... lo spazio allocato dalla malloc è allocato nello heap, questo significa che si tratta di un area di memoria con politiche totalmente differenti dallo stack.
Tutto ciò che è allocato nello heap deve essere deallocato manualmente.
Il che significa che se dimentichi di deallocare la memoria che hai occupato con chiamate *alloc incorri nei tanto odiati memory leak, in quanto quella memoria è praticamente perduta nell'ambito di quel processo.
dichiarazioni, invece, del tipo
int a;
char ar[DIM];
gatto *miogatto;
provocano delle allocazioni nello spazio di memoria stack e vengono automaticamente deallocate all'uscita dalla funzione.
Questo provoca che ad esempio non puoi restituire l'array ar perchè avresti un riferimento a memoria non valida.
Se da un lato potresti avere una bellissima segmentation fault dall'altro lato potresti essere così sfortunato che il programma continuerà a girare assumendo alla lunga un comportamento bizantino che ti complicherà la vita anche nella sessione di debug.
Esistono altre aree di memoria... facendo riferimento al C++ ad esempio esiste la memoria libera che è quella utilizzata quando allochi qualcosa con new ed ha più o meno le stesse politiche dello heap.
Come potrai immaginare non è affatto consigliabile allocare qualcosa con new e deallocarla con una free() o viceversa.
Di solito più o meno funziona così!
in pratica con una malloc allochi memoria raw... n byte di memoria e viene restituito l'indirizzo iniziale di questi n byte. Quindi quello che perdi quando esci dalla funzione non è la memoria allocata, bensì il puntatore che utilizzi per accedere all'area che hai allocato.
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:34
da boh
Spiegazione esemplare, grazie
Un'ultima cosa: per il programma che è questo penso sia ininfluente, ma dovesse capitarmi qualcosa
di più "corposo" come allocazione, allora sarebbe preferibile, dopo che nel main ho usato quella memoria, fare un bel free?
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:34
da robbybby
@boh
In
Codice: Seleziona tutto
p = (char *)malloc((N+N)*sizeof(char));
strcat(p, str1);
strcat(p, str2);
C'e' un errore.
A te trovarlo.
Il free lo devi fare sempre. Questa e' una delle ragioni per cui, in un programma vero, una funzioni siffatta non sarebbe molto bella.
Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:36
da boh
Strano perchè funziona
La prima cosa che mi viene in mente è che la strcat restituisce, da prototipo, un char *, e quindi sarebbe preferibile:
EDIT: Ok

Re: [C]return di una stringa
Inviato: mar 26 feb 2008, 21:38
da Blizzard
C'e' un errore.
A te trovarlo.

stavolta mi faccio i * miei!
Il free lo devi fare sempre. Questa e' una delle ragioni per cui, in un programma vero, una funzioni siffatta non sarebbe molto bella.
infatti straquoto la prima soluzione che hai postato che è senza dubbio infinitamente elegante