Repository 32bit  Forum
Repository 64bit  Wiki

[RISOLTO][C]return di una stringa

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

[RISOLTO][C]return di una stringa

Messaggioda boh » mar feb 26, 2008 20:24

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?
Ultima modifica di boh il mer feb 27, 2008 10:55, modificato 1 volta in totale.
"Be yourself. Everyone else is already taken." ~ Oscar Wilde
Avatar utente
boh
Linux 2.6
Linux 2.6
 
Messaggi: 953
Iscritto il: gio set 15, 2005 23:00
Località: Milano
Slackware: 14.1 (x64)
Kernel: 3.14.1
Desktop: KDE 4.13.3

Re: [C]return di una stringa

Messaggioda absinthe » mar feb 26, 2008 20:48

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 ? ;-)
Avatar utente
absinthe
Iper Master
Iper Master
 
Messaggi: 2354
Iscritto il: sab mag 14, 2005 23:00
Località: Prato
Nome Cognome: Matteo Nunziati
Slackware: 12.1 - defunct
Kernel: 2.6.32-5-amd64
Desktop: gnome
Distribuzione: debian squeeze

Re: [C]return di una stringa

Messaggioda robbybby » mar feb 26, 2008 20:50

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

Avatar utente
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1176
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: [C]return di una stringa

Messaggioda boh » mar feb 26, 2008 20:52

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 ;)
"Be yourself. Everyone else is already taken." ~ Oscar Wilde
Avatar utente
boh
Linux 2.6
Linux 2.6
 
Messaggi: 953
Iscritto il: gio set 15, 2005 23:00
Località: Milano
Slackware: 14.1 (x64)
Kernel: 3.14.1
Desktop: KDE 4.13.3

Re: [C]return di una stringa

Messaggioda robbybby » mar feb 26, 2008 20:57

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! :D ) e ai copy constructor :) .
Ultima modifica di robbybby il mar feb 26, 2008 21:07, modificato 1 volta in totale.
Avatar utente
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1176
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: [C]return di una stringa

Messaggioda boh » mar feb 26, 2008 21:01

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...
"Be yourself. Everyone else is already taken." ~ Oscar Wilde
Avatar utente
boh
Linux 2.6
Linux 2.6
 
Messaggi: 953
Iscritto il: gio set 15, 2005 23:00
Località: Milano
Slackware: 14.1 (x64)
Kernel: 3.14.1
Desktop: KDE 4.13.3

Re: [C]return di una stringa

Messaggioda robbybby » mar feb 26, 2008 21:06

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() :)
Avatar utente
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1176
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: [C]return di una stringa

Messaggioda Blizzard » mar feb 26, 2008 21:08

[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
Ultima modifica di Blizzard il mar feb 26, 2008 21:17, modificato 1 volta in totale.
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: [C]return di una stringa

Messaggioda robbybby » mar feb 26, 2008 21:13

@Blizzard
Si', ma volevo che la trovasse da se', la soluzione.
Come ho detto prima, la vedo una soluzione valida solo a scopo didattico.
Avatar utente
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1176
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: [C]return di una stringa

Messaggioda boh » mar feb 26, 2008 21:15

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 :D
Ma a questo punto avrei una domanda: perchè lo spazio che ho appena allocato nella funzione non sparisce?
Non è anche quello locale?
"Be yourself. Everyone else is already taken." ~ Oscar Wilde
Avatar utente
boh
Linux 2.6
Linux 2.6
 
Messaggi: 953
Iscritto il: gio set 15, 2005 23:00
Località: Milano
Slackware: 14.1 (x64)
Kernel: 3.14.1
Desktop: KDE 4.13.3

Re: [C]return di una stringa

Messaggioda Blizzard » mar feb 26, 2008 21:30

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.
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: [C]return di una stringa

Messaggioda boh » mar feb 26, 2008 21:34

Spiegazione esemplare, grazie :D
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?
Codice: Seleziona tutto
free(ptr);
"Be yourself. Everyone else is already taken." ~ Oscar Wilde
Avatar utente
boh
Linux 2.6
Linux 2.6
 
Messaggi: 953
Iscritto il: gio set 15, 2005 23:00
Località: Milano
Slackware: 14.1 (x64)
Kernel: 3.14.1
Desktop: KDE 4.13.3

Re: [C]return di una stringa

Messaggioda robbybby » mar feb 26, 2008 21:34

@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.
Avatar utente
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1176
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: [C]return di una stringa

Messaggioda boh » mar feb 26, 2008 21:36

Strano perchè funziona :-k

La prima cosa che mi viene in mente è che la strcat restituisce, da prototipo, un char *, e quindi sarebbe preferibile:
Codice: Seleziona tutto
p = strcat(p, str1);
p = strcat(p, str2);


EDIT: Ok ;)
"Be yourself. Everyone else is already taken." ~ Oscar Wilde
Avatar utente
boh
Linux 2.6
Linux 2.6
 
Messaggi: 953
Iscritto il: gio set 15, 2005 23:00
Località: Milano
Slackware: 14.1 (x64)
Kernel: 3.14.1
Desktop: KDE 4.13.3

Re: [C]return di una stringa

Messaggioda Blizzard » mar feb 26, 2008 21:38

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
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Prossimo

Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti