[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.
Avatar utente
boh
Linux 4.x
Linux 4.x
Messaggi: 1027
Iscritto il: ven 16 set 2005, 0:00
Slackware: 14.2 (x64)
Kernel: 4.4.111
Desktop: KDE 4.14.32
Località: Milano
Contatta:

Re: [C]return di una stringa

Messaggio da boh »

E manca l'eventuale spazio per il terminatore ;)

Codice: Seleziona tutto

p = (char *)malloc((N+N+1)*sizeof(char));
"Be yourself. Everyone else is already taken." ~ Oscar Wilde

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Re: [C]return di una stringa

Messaggio da Blizzard »

comunque un piccolo appunto.... che non riguarda la correttezza del codice ma la pignoleria...
su comp.lang.c una volti mi ci fecero il **** :D

Codice: Seleziona tutto

 p = (char *)malloc(N+N+1 /*dato che hai trovato la soluzione lo aggiungo*/)*sizeof(char));
la sintassi corretta per quello che ne so è

Codice: Seleziona tutto

 p = malloc(N+N+1 /*dato che hai trovato la soluzione lo aggiungo*/);
prima cosa perchè la malloc restituisce un void* su cui non va fatto il cast e poi perchè il char occupa 1 byte praticamente su tutte le architetture.
Il cast su una malloc va utilizzato solo se stai utilizzando codice ibrido con il C++
ma come ho detto si tratta di pignoleria... io stesso utilizzo il cast perchè semanticamente mi ritrovo codice maggiormente leggibile, tuttavia su comp.lang.c mi hanno detto che questo potrebbe portare a comportamenti indefiniti...
e quelli ne sanno!

inoltre è sempre buona regola inizializzare a NULL ogni nuovo puntatore dichiarato.

ciao
Gio

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

Re: [C]return di una stringa

Messaggio da robbybby »

Blizzard ha scritto: infatti straquoto la prima soluzione che hai postato che è senza dubbio infinitamente elegante
Blizzard ha scritto: E volendo, le puoi far ritornare un puntare al suo argomento di stringa concatenata (szSum): a volte risulta comodo: per esempio, la strcpy fa proprio cosi'.
Esatto! E' buona regola inizializzare TUTTO! Stroustrup docet.

inoltre è sempre buona regola inizializzare a NULL ogni nuovo puntatore dichiarato.

@boh: il buon funzionamente della tua soluzione e' random. Suggerimento: pensa alla prima strcat() :)

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Re: [C]return di una stringa

Messaggio da Blizzard »

@boh: il buon funzionamente della tua soluzione e' random. Suggerimento: pensa alla prima strcat() :)
cavolo! non l'avevo visto :D :D
mi ci sono piantato una volta mentre scrivevo la shell per una cavolata simile!
sono gli errori più viscidi perchè la sfortuna vuole che le cose ti funzionano :D
poi la prossima volta che esegui ti bestemmia tutto!

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

Re: [C]return di una stringa

Messaggio da robbybby »

boh ha scritto:E manca l'eventuale spazio per il terminatore ;)

Codice: Seleziona tutto

p = (char *)malloc((N+N+1)*sizeof(char));
No, lo spazio per il terminatore c'e' (anzi, ce n'e' uno in piu'), perche' le stringhe in input sono lunghe, al max, N caratteri, terminatore compreso, dato che sono dichiarate con qualcosa tipo:

Codice: Seleziona tutto

char str[N]
e non

Codice: Seleziona tutto

char str[N+1]

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [C]return di una stringa

Messaggio da Mario Vanoni »

#include <stdio.h>
#include <string.h>

char *boh(char *a, char *b)
{
static char out[4096];
strcpy(out, a);
strcat(out, b);
return(out);
}

int main(int argc, char **argv)
{
return(printf("%s", boh(argv[1], argv[2])));
}

a.out anna bella
annabella

Avatar utente
boh
Linux 4.x
Linux 4.x
Messaggi: 1027
Iscritto il: ven 16 set 2005, 0:00
Slackware: 14.2 (x64)
Kernel: 4.4.111
Desktop: KDE 4.14.32
Località: Milano
Contatta:

Re: [C]return di una stringa

Messaggio da boh »

@Blizzard: guarda il casting della malloc è pignoleria della mia prof, quindi figurati :D

Veramente io le ho dichiarate con N+1 caratteri.
Per il resto mi arrendo, qual'è il problema?

@Mario: grazie della risposta, ora la provo! :)
"Be yourself. Everyone else is already taken." ~ Oscar Wilde

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Re: [C]return di una stringa

Messaggio da Blizzard »

ora che mi ero convinto anch'io che era meglio che ci arrivasse da solo :lol:

Codice: Seleziona tutto

char *boh(char *a, char *b)
{
static char out[4096];
strcpy(out, a);
strcat(out, b);
return(out);
}
perchè adotti questa soluzione???
gia lo static di per se non lo amo... ma poi la soluzione non è adattiva ma devi restare sempre nel range di caratteri 4095+1
inoltre con la static se non sbaglio se richiami la funzione vai a sovrascrivere il dato che hai precedentemente restituito e questo è codice pericoloso..

dico fandonie?????

Avatar utente
Blizzard
Master
Master
Messaggi: 1509
Iscritto il: mar 2 gen 2007, 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox
Contatta:

Re: [C]return di una stringa

Messaggio da Blizzard »

@Blizzard: guarda il casting della malloc è pignoleria della mia prof, quindi figurati :D
figurati anche un mio professore... poi con in pompa magna il Kerningan&Ritchie me ne sono convinto anche io!
poi mi hanno fatto notare che il libro è alquanto vecchio :D

{nutro comunque infinito rispetto per quel libro che è comunque uno dei testi sacri della mia libreria}

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

Re: [C]return di una stringa

Messaggio da robbybby »

@Mario Vanoni
Non trovi che la soluzione con la malloc() che alloca il numero esatto di caratteri sia piu' elegante? Stiamo parlando di programmini didattici. :)
Sicuramente la tua funzione e' ok, e sul programmino di boh funzionera' bene.

@Blizzard
Sicuramente la soluzione di Mario e' un po' sprecona, ma funzionale per un programmino di esempio. Comunque lo static per questi scopi non piace nemmeno a me.
Lo avevo gia' detto anch'io che si poteva usare una variabile globale, ma che la soluzione non mi piaceva.
E comunque non e' esente da problemi nemmeno la soluzione col malloc().
Io continuo a preferire la prima soluzione che ho postato, ma non si confa' coi dati del problema di boh.
Tutte le altre soluzioni che abbiamo dato (me compreso) sono solo degli accrocchi per adeguarsi ai dati del problema (mal posto per un caso reale, ma valido a fini didattici, perche' ti fa capire cosa NON fare conle variabili automatiche).

Il K&R e' vecchio, ma rimane la bibbia del C.

Avatar utente
ksniffer
Linux 3.x
Linux 3.x
Messaggi: 540
Iscritto il: lun 30 lug 2007, 13:18
Kernel: 2.6.34
Desktop: KDE 4.4.4
Distribuzione: ArchLinux
Contatta:

Re: [C]return di una stringa

Messaggio da ksniffer »

robbybby ha scritto:@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.
Per caso deve essere:

p = (char *)malloc((N+N+1)*sizeof(char));

strcat(p, str1);
strcat(p, str2);

Sì?

Mario Vanoni
Iper Master
Iper Master
Messaggi: 3174
Iscritto il: lun 3 set 2007, 21:20
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey
Località: Cuasso al Monte (VA)

Re: [C]return di una stringa

Messaggio da Mario Vanoni »

Blizzard ha scritto:ora che mi ero convinto anch'io che era meglio che ci arrivasse da solo :lol:

Codice: Seleziona tutto

char *boh(char *a, char *b)
{
static char out[4096];
strcpy(out, a);
strcat(out, b);
return(out);
}
perchè adotti questa soluzione???
gia lo static di per se non lo amo... ma poi la soluzione non è adattiva ma devi restare sempre nel range di caratteri 4095+1
inoltre con la static se non sbaglio se richiami la funzione vai a sovrascrivere il dato che hai precedentemente restituito e questo è codice pericoloso..

dico fandonie?????
- KISS rule
- puoi definire out[N + 1] con un #define N 1234 prima,
> sai quanto ti serve, metti il decuplo, con la HW di oggi non conta,
> con il 3B2 dei tempi, OK, ogni byte contava, allora 512KB, oggi ho 4GB di memoria
- static perche` e` e rimane proprieta` della funzione boh()
- e per andare sicuro, scusa la dimenticanza, dopo
> static char out[4096]
> out[0] = '\0';

@boh
aggiungi la riga sopra citata, scusa ul vecc

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

Re: [C]return di una stringa

Messaggio da robbybby »

Mario Vanoni ha scritto: > con il 3B2 dei tempi, OK, ogni byte contava, allora 512KB, oggi ho 4GB di memoria
Non sempre: c'e' chi fa andare ancora aggeggi con il DOS (freedos, oggi), e 640 k di memoria. Vedi il sottoscritto. E li' mi serve anche il byte. :)
ksniffer ha scritto:Per caso deve essere:

p = (char *)malloc((N+N+1)*sizeof(char));

strcat(p, str1);
strcat(p, str2);

Sì?
No :)
Ultima modifica di robbybby il mar 26 feb 2008, 22:29, modificato 1 volta in totale.

Avatar utente
boh
Linux 4.x
Linux 4.x
Messaggi: 1027
Iscritto il: ven 16 set 2005, 0:00
Slackware: 14.2 (x64)
Kernel: 4.4.111
Desktop: KDE 4.14.32
Località: Milano
Contatta:

Re: [C]return di una stringa

Messaggio da boh »

Mario Vanoni ha scritto: > out[0] = '\0';

@boh
aggiungi la riga sopra citata, scusa ul vecc
Ah ora ho capito!
La strcat sostituisce il terminatore con il primo carattere della stringa da concatenare, ma essendo che
non c'è ancora alcun terminatore all'interno di p, funziona appunto a random :D
La strcpy d'altro canto copia anche il terminatore, quindi è rigoroso prima una strcpy e poi una strcat, è questo giusto?
(grazie ancora a Mario!)
"Be yourself. Everyone else is already taken." ~ Oscar Wilde

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

Re: [C]return di una stringa

Messaggio da robbybby »

boh ha scritto: Ah ora ho capito!
La strcat sostituisce il terminatore con il primo carattere della stringa da concatenare, ma essendo che
non c'è ancora alcun terminatore all'interno di p, funziona appunto a random :D
La strcpy d'altro canto copia anche il terminatore, quindi è rigoroso prima una strcpy e poi una strcat, è questo giusto?
(grazie ancora a Mario!)
Bravo! Giusto, ma con una piccola inesattezza :)
Entrambe copiano anche il terminatore, ma la strcpy parte dall'inizio della stringa, mentre la strcat parte dal primo NULL che trova.
Quindi, prima strcpy() e poi strcat().

Rispondi