View Full Version : [C] Concatenazione stringhe statica e dinamica
k_mishima
15-05-2007, 21:01
Ciao a tutti, devo fare questo esercizio
Scrivere function C che, confrontando il risultato ottenuto mediante strcat(...),
restituisce la concetenazione di due stringhe senza usare strcat (...) mediante:
1 Allocazione statica
2 Allocazione dinamica e le funzioni memcpy(...) e memmove(...)
La parte statica l'ho fatta, quella dinamica non funziona ed è incompleta.
P.s. Ci sono 2 main perchè ho iniziato facendo gli esercizi separatamente poi in seguito vorrei unire il tutto.
/*
#include <stdio.h>
#include <string.h>
#define N 30
void strcat_allocazione_statica (char a[], char b[], char c[],int *prova);
main()
{
char a[N],b[N],c[N];
int d,prova;
short i,nn;
puts("Scrive 1 parola");
gets(a);
puts("Scrivine un'altra");
gets(b);
strcat_allocazione_statica(a,b,c,&prova);
nn=strlen(c);
puts("\n\nStringa senza strcat");
for (i=0;i<nn;i++)
printf("%c",c[i]);
puts("\n\nLa concatenazione e' ok se il risultato e' 1, altrimenti no");
printf("%d\n",prova);
system("pause");
}
void strcat_allocazione_statica (char a[], char b[], char c[], int *prova)
{
short i,n1,n2;
n1=strlen(a);
n2=strlen(b);
for (i=0;i<n1;i++)
c[i]=a[i];
for (i=0;i<n2;i++)
c[n1+i]=b[i];
strcat(a,b);
puts("Stringa con strcat");
for (i=0;i<n1+n2;i++)
printf("%c",a[i]);
for (i=0;i<n1+n2;i++)
if (a[i]==c[i])
*prova=1;
else
*prova=0;
}
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void strcat_allocazione_dinamica(char *a, char *b,char *c);
main()
{
char *a, *b, *c;
puts("Digita 1 stringa");
gets(a);
puts("Digita un'altra stringa");
gets(b);
strcat_allocazione_dinamica(a,b,c);
puts("Risultato");
printf("%s",c);
free(c);
system("pause");
}
void strcat_allocazione_dinamica(char *a,char *b,char *c)
{
short n1,n2,n3;
n1=strlen(a);
n2=strlen(b);
n3=n1+n2;
c=(char *)malloc(n3);
memcpy(c,a,n1);
memmove(c+n1,b,n2);
}
Devo aver fatto un bel pasticcio nella function dinamica mi sa, cmq è la prima volta che provo con la modalita' dinamica :D
vegeta83ssj
15-05-2007, 21:54
Se non ricordo male il C dovresti fare coì per la malloc:
c=(char *)malloc(n3*sizeof(char));
da prendere con le molle però perchè è un pò che non bazzico il C.
Ciauz
è giusto fare la malloc mettendo anche il sizeof dell'elemento
in questo caso sizeof(char) è 1 quindi va bene mettere solo n3, ma è buona abitudine tenere il sizeof, non si sa mai :)
il problema qual è esattamente? c'è un segmentation fault da qualche parte?
Come fai a ritornare il vettore c allocato al chiamante ?
Se fai così dovrebbe funzionare:
char * strcat_allocazione_dinamica(char *a,char *b)
In alternativa puoi fare:
void strcat_allocazione_dinamica(char *a,char *b,char **c)
Attenzione al carattere di fine stringa, n3 deve essere n1 + n2 + 1.
k_mishima
16-05-2007, 14:27
Grazie 1000 per le risposte, ho aggiunto quello che avete suggerito
main()
{
char *a, *b, *c;
puts("Digita 1 stringa");
gets(a);
puts("Digita un'altra stringa");
gets(b);
strcat_allocazione_dinamica(a,b,&c);
puts("Risultato");
printf("%s",c);
free(c);
system("pause");
}
void strcat_allocazione_dinamica(char *a,char *b,char **c)
{
short n1,n2,n3;
n1=strlen(a);
n2=strlen(b);
n3=n1+n2+1;
*c=(char *)malloc(n3*sizeof(char));
memcpy(*c,a,n1);
memmove(*c+n1,b,n2);
}
@cionci
Ho messo il +1 e i puntatori, cmq c'è ancora qualcosa che non va.
@vegeta83ssj
Ricordi bene ma come ha detto recoil si puo' farne a meno, cmq l'ho messo
@recoil
Cos'è un segmentation fault? LOL
Cmq mi crasha quando inserisco la 2a parola
Devi aggiungere il carattere di fine stringa in fondo alla stringa c...oppure lo copi dalla seconda stringa:
memmove(*c+n1,b,n2+1);
ps: strcat non fa esattamente quello che fai te: http://www.cplusplus.com/reference/clibrary/cstring/strcat.html
Non mi torna anche questa cosa che hai fatto:
char *a, *b, *c;
puts("Digita 1 stringa");
gets(a);
puts("Digita un'altra stringa");
gets(b);
In questo modo non allochi lo spazio per le stringhe a e b...
k_mishima
16-05-2007, 17:13
Non mi torna anche questa cosa che hai fatto:
char *a, *b, *c;
puts("Digita 1 stringa");
gets(a);
puts("Digita un'altra stringa");
gets(b);
In questo modo non allochi lo spazio per le stringhe a e b...
mmmm, e come dovrei fare ad allocarlo? Con malloc no perchè non posso fare la strlen se non ho preso ancora "a" e "b" :D
per il fatto della strcat ho visto che mette anche uno spazio tra le parole, intendi questo come errore?
No...strcat non mette lo spazio fra le parole. E' diverso anche il numero di argomenti fra le tue strcat e la strcat del C ;) E' quello che ti volevo far notare...
Purtroppo ti trovi di fronte ad uno dei grandi problemi del C, la possibilità di buffer overflow con la libreria standard...per questo per la lettura di stringhe si usa sempre fgets al posto di gets...infatti in questo modo si può limitare il numero di caratteri letti...
char s[20]; /* 19 caratteri + fine stringa */
fgets(s, 19, stdin);
Quindi o fai come ho fatto sopra...oppure non ti preoccupi della dimensione del buffer in ingresso ed usi gets allocando le due stringhe in ingresso a dimensioni massime che decidi tu...
Ovviamente se l'utente inserisce più dei caratteri che hai previsto in una sola parola il programma potrebbe andare incontro a blocchi improvvisi o malfunzionamenti...
No...strcat non mette lo spazio fra le parole. E' diverso anche il numero di argomenti fra le tue strcat e la strcat del C ;) E' quello che ti volevo far notare...
Purtroppo ti trovi di fronte ad uno dei grandi problemi del C, la possibilità di buffer overflow con la libreria standard...per questo per la lettura di stringhe si usa sempre fgets al posto di gets...infatti in questo modo si può limitare il numero di caratteri letti...
queste cose non si ripetono mai abbastanza
le security flaws relative al buffer overflow sono note da secoli e si scrive ancora codice insicuro
eppure, per evitare buona parte dei problemi, basterebbe un minimo di attenzione
hai fatto bene a sottolineare sta cosa
stesso discorso per le funzioni tipo strlen ecc.
ci sono le funzioni con la dimensione massima della stringa, usiamole :)
k_mishima
17-05-2007, 16:59
ok, ma io queste cose ancora non le ho fatte, per ora mi devo limitare a fare questi esercizi a livello piu' basso, senza preoccuparmi delle possibili cause di malfunzionamento dovuti a casi particolari tipo il buffer overlflow di cui parlate.
Per ora sono ancora bloccato al codice del mio messaggio precedente, non ho capito come allocare a e b.
Come faccio? Grazie
Metti una dimensione onesta sperando che l'utente non immetta troppi caratteri ;)
Le allochi in modo statico o dinamico, è indifferente...
k_mishima
17-05-2007, 18:05
Non ci siamo capiti mi sa.
Non lo so fare, potresti buttare giu' 2 righe di codice tu?
Li vorrei allocare dinamicamente ma non lo so fare, mi serve una mano da voi.
Staticamente uso array di caratteri
char c[qualcosa];
E dinamicamente?
Con malloc...l'hai scritto anche sopra...
a = (char *)malloc(qualcosa*sizeof(char));
k_mishima
17-05-2007, 18:54
Ahhhhhhhhhhhhhhhhhhhhhh
Ora vedendolo scritto mi è chiaro.
Cioè io quel "qualcosa" posso darlo anche grandissimo perchè tanto essendo dinamica la cosa verrà cancellato e non si sprecherà spazio giusto?
Mi ero perso questo passaggio, invece del "qualcosa" nella formula ci volevo mettere la lunghezza di a e b, ma non sapevo come fare dato che per leggerle dovevo prima aver allocato lo spazio :O
Provo e dopo posto i risultati, grazie cionci
Edit:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void strcat_allocazione_dinamica(char *a,char *b,char **c);
main()
{
char *a, *b, **c;
a=(char *)malloc(20*sizeof(char));
puts("Digita 1 stringa");
gets(a);
b=(char *)malloc(20*sizeof(char));
puts("Digita un'altra stringa");
gets(b);
strcat_allocazione_dinamica(a,b,c);
puts("Risultato");
printf("%s",*c);
printf("\n");
free(c);
system("pause");
}
void strcat_allocazione_dinamica(char *a,char *b,char **c)
{
short n1,n2,n3;
n1=strlen(a);
n2=strlen(b);
n3=n1+n2+1;
*c=(char *)malloc(n3*sizeof(char));
memcpy(*c,a,n1);
memmove(*c+n1,b,n2);
}
Ancora non viene, non sempre, ma a volte nella stampa mi ritrovo di seguito alla soluzione molti caratteri ascii strani tipo
»«¼½
k_mishima
18-05-2007, 14:28
help me
tomminno
18-05-2007, 17:00
Ancora non viene, non sempre, ma a volte nella stampa mi ritrovo di seguito alla soluzione molti caratteri ascii strani tipo
»«¼½
Dopo aver fatto la malloc prova ad usare:
memset(a,0,20);
dopo aver eseuito la malloc. Una stringa in C finisce con il carattere '\0', ma quando allochi non conosci il contenuto della memoria perciò la stampa prosegue anche oltre il dovuto.
k_mishima
19-05-2007, 20:38
e non posso inserire il carattere di fine stringa sfruttando gli indirizzi?
ho provato ma non ci sono riuscito, con l'array sarebbe stato piu' facile
come dovrei fare?
k_mishima
21-05-2007, 14:33
up
k_mishima
22-05-2007, 13:31
dai, manca un'anticchia per finirlo
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void strcat_allocazione_dinamica(char *a,char *b,char **c);
main()
{
char *a, *b, *c;
a=(char *)malloc(20*sizeof(char));
puts("Digita 1 stringa");
gets(a);
b=(char *)malloc(20*sizeof(char));
puts("Digita un'altra stringa");
gets(b);
strcat_allocazione_dinamica(a,b,&c);
puts("Risultato");
printf("%s",c);
printf("\n");
free(c);
system("pause");
}
void strcat_allocazione_dinamica(char *a,char *b,char **c)
{
short n1,n2,n3;
n1=strlen(a);
n2=strlen(b);
n3=n1+n2+1;
*c=(char *)malloc(n3*sizeof(char));
memcpy(*c,a,n1);
memmove(*c + n1, b, n2 + 1);
}
Te l'avevo detto che ci voleva il + 1 sulla memmove per copiare il carattere di finestringa ;)
k_mishima
22-05-2007, 16:43
Ah, cosi' gli dai lo /0 della stringa b, ottimo
io invece stavo provando a darlo a mano facendo qualcosa tipo
*c+n3=(char)"/0";
ma mi da un errore : invalid lvalue in assignment
vorrei imparare bene la sintassi per muovermi tramite indirizzo, dov'è che ho sbagliato?
Grazie
*c + (n3 - 1) = '/0';
I char singoli si mettono fra apici singoli. Fai qualche conto per capire il perchè del -1 ;)
k_mishima
22-05-2007, 20:32
Si, mi sono fatto i conti ed è giusto.
Pero' da 1 errore e 1 warning
invalid lvalue in assignment
[Warning] multi-character character constant
uso dev-c++ 4.9.9.2
:eek:
Intanto è \0 e non /0 ;) L'avevo copiato dal tuo post e non me ne ero accorto :D
(*c)[n3 + 1] = '\0';
Evidentemente l'aritmetica dei puntatori non può essere usata come valore sinistro di una espressione...non mi era mai capitato di usarlo in questo modo...
k_mishima
23-05-2007, 14:53
Alleluia, l'esercizio è completo
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void strcat_allocazione_dinamica(char *a,char *b,char **c, short *x);
main()
{
char *a, *b, *c;
short x;
a=(char *)malloc(20*sizeof(char));
puts("Digita 1 stringa");
gets(a);
b=(char *)malloc(20*sizeof(char));
puts("Digita un'altra stringa");
gets(b);
strcat_allocazione_dinamica(a,b,&c,&x);
puts("Risultato");
printf("%s",c);
printf("\nSe l'esercizio e' corretto uscira' 1, altrimenti 0\n%hd\n",x);
free(a);
free(b);
free(c);
system("pause");
}
void strcat_allocazione_dinamica(char *a,char *b,char **c, short *x)
{
short n1,n2,n3,i;
n1=strlen(a);
n2=strlen(b);
n3=n1+n2+1;
*c=(char *)malloc(n3*sizeof(char));
memcpy(*c,a,n1);
memmove(*c+n1,b,n2);
(*c)[n3-1]='\0';
strcat(a,b);
for (i=0;i<n3;i++)
if (a[i]==(*c)[i])
*x=1;
else
*x=0;
}
Ho aggiunto anche la parte che verica se l'eserizio è venuto come se si fosse usata una strcat :D
Grazie mille a tutti, specialmente a cionci
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.