View Full Version : Funzioni in C
potete darmi qualche aiutino su come sovlgere questo esercizio?
domani leggerò i messaggi
grazie in anticipo
Si scriva una funzione
char*_strncat_(char*s1, const char*s2, int n);
tale funzione appende al massimo n caratteri della stringa s2 allafine della stringa s1. In particolare appende a s1 n caratteri di s2 se s2 contiene n caratteri validi, il numero di caratteri validi di s2 altrimenti. Il primo carattere di s2 va a sovrascrivere il carattere '\0' di terminazione della stringa s1. Una volta appesi i caratteri di s2 a s1 si dovra terminare la stringa s1 cosi modificata con un carattere di fine stringa. La funzione strncat restituisce un puntatore alla stringa s1 cosi modificata.
Esempio: se s1 è la stringa pippo
s2 è la stringa pluto e n vale 20
la funzione restituirà un puntatore a s1 modificata in modo da contenere pippopluto
se s1 è la stringa pippo
s2 è la stringa pluto e n vale 0
la funzione restituirà un puntatore a s1 modificata in modo da contenere pippo
se s1 è la stringa pippo
s2 è la stringa pluto e n vale 3
la funzione restituirà un puntatore a s1 modificata in modo da contenere pippoplu
TuLKaS85
12-11-2006, 10:34
se sono allocati dinamicamente gli array di stringhe puoi usare memcpy e subito fai
n1=strlen(s1); //metti la lunghezza della prima stringa
memcpy((s1+n1),s2,n); //copia a partire dalla fine di s1 n caratteri di s2
*(s1+n1+n)='\0';
return *s1; // io la farei come void cmq....
versione alternativa allocazione statica...
n1=strlen(s1);
for(i=n1;i<n;i++)
s1[i]=s2[i-n1];
s1[i]='\0';
provali magari c'è qualche imperfezione, ma x grandi linee ci siamo :D
ti ringrazio per l'aiuto, li vedrò attentamente da domani e ti farò sapere
quindi se l'esercizio mi chiede "si scriva una funzione", in pratica io cosa devo scrivere?
sono giuste quelle due che mi hai scritto qui sopra? cosa dovrei aggiustarci?
TuLKaS85
13-11-2006, 15:45
nulla, devi aggiungere solo il prototipo della function...
quindi se l'esercizio mi chiede "si scriva una funzione", in pratica io cosa devo scrivere?Scrivi una funzione
char*_strncat_(char*s1, const char*s2, int n)
{
....
}
provali magari c'è qualche imperfezione, ma x grandi linee ci siamo :DC'è un piccolo dettaglio che non hai considerato: la stringa s2 può anche avere meno caratteri rispetto a quanto indicato in 'n'.
char*_strncat_(char*s1, const char*s2, int n)
{
n1=strlen(s1);
for(i=n1;i<n;i++)
s1[i]=s2[i-n1];
s1[i]='\0';
}
è giusta? penso di no
cosa c'è che non va?
TuLKaS85
13-11-2006, 16:08
C'è un piccolo dettaglio che non hai considerato: la stringa s2 può anche avere meno caratteri rispetto a quanto indicato in 'n'.
ah giusto, vabbè semplice da risolvere strlen di s2 e confronto con n poi avanti ...
char*_strncat_(char*s1, const char*s2, int n)
{
n1=strlen(s1);
for(i=n1;i<n;i++)
s1[i]=s2[i-n1];
s1[i]='\0';
}
puoi dirmi come si corregge questa?
puoi dirmi come si corregge questa?Ti spiego a parole cosa dovrebbe fare la funzione (se scrivo il codice ... lo faccio io l'esercizio ;) ).
a) Devi calcolare la lunghezza di s1 (con strlen).
b) Devi ottenere un puntatore che punta al carattere nullo di s1 (puoi usare s1 stesso come puntatore, aggiungi ad s1 il valore della lunghezza di s1).
c) Copi i caratteri da s2 in poi a (s1+n1) in poi fino a quando (1) hai raggiunto il carattere nullo di s2 oppure (2) hai copiato 'n' caratteri.
d) Accodi il carattere nullo.
a ma ci servono i puntatori. ancora deve spiegarli la prof.
a ma ci servono i puntatori. ancora deve spiegarli la prof.Guarda che stai usando dei puntatori!! s1 s2 sono puntatori e fare s1[i] è esattamente come fare *(s1+i)
Ti spiego a parole cosa dovrebbe fare la funzione (se scrivo il codice ... lo faccio io l'esercizio ).
a) Devi calcolare la lunghezza di s1 (con strlen).
b) Devi ottenere un puntatore che punta al carattere nullo di s1 (puoi usare s1 stesso come puntatore, aggiungi ad s1 il valore della lunghezza di s1).
c) Copi i caratteri da s2 in poi a (s1+n1) in poi fino a quando (1) hai raggiunto il carattere nullo di s2 oppure (2) hai copiato 'n' caratteri.
d) Accodi il carattere nullo
a) come si fa a calcolare la lunghezza di s1, cioè cos'è strlen?
lo so, ma ho cominciato oggi a leggere i puntatori, non sono cosi bravo nell'usarli, figuriamoci per fare un esercizio del genere
Lasciamolo perdere per un po st'esercizio, voglio cercare di farne prima un'altro che mi sembra piu semplice.
Si scriva una funzione che dato un vettori di interi lo inverta
void_inverti_vett_(int vett[], int n);
Esempio:
se il vettore di interi vett contiene n=7 elementi
1234567
dopo la chiamata della funzione conterrà
7654321
a) come si fa a calcolare la lunghezza di s1, cioè cos'è strlen?Sì.
Allora:
1) Prendi la lunghezza della stringa s1:
int n1 = strlen (s1);
2) Il carattere nullo di s1 si trova in s1[n1]. Da lì in poi dovrai copiare s2.
3) Fai un ciclo for da 0 a < n. Nel blocco del for devi:
- Testare se s2[i] è nullo e in tal caso devi uscire dal for con un break.
- Copiare il carattere da s2[i] a s1[n1+i]
4) Finito il ciclo metti il nullo in s1[n1+i]
ti ringrazio, ma voglio cercare di fare prima l'altro esercizio, sembra piu facile. è cosi? :D
come potrei agire per farlo?
Si scriva una funzione che dato un vettori di interi lo inverta
void_inverti_vett_(int vett[], int n);
Esempio:
se il vettore di interi vett contiene n=7 elementi
1234567
dopo la chiamata della funzione conterrà
7654321
Si scriva una funzione che dato un vettori di interi lo inverta
void_inverti_vett_(int vett[], int n);
Esempio:
se il vettore di interi vett contiene n=7 elementi
1234567
dopo la chiamata della funzione conterrà
7654321Ok, molto semplice.
a) Prendi 'n' e lo dividi per 2 (n non lo devi alterare, usa un'altra variabile). Se 'n' vale per esempio 7, ottieni 3 (nota, la divisione è intera). Se il numero è dispari, l'elemento centrale non verrà toccato/spostato (ovvio).
b) Fai un ciclo for da 0 a < m. (dove m è n/2). Nel blocco del for devi:
- mettere in una variabile temporanea vett[i]
- mettere in vett[i] il valore di vett[n-i-1]
- mettere in vett[n-i-1] il valore temporaneo
a) Prendi 'n' e lo dividi per 2 (n non lo devi alterare, usa un'altra variabile). Se 'n' vale per esempio 7, ottieni 3 (nota, la divisione è intera). Se il numero è dispari, l'elemento centrale non verrà toccato/spostato (ovvio).
PER ESEMPIO POSSO FARE: m=n/2 ??? MA SI PUO INSERIRE UN'ALTRA VARIABILE ALL'INTERNO DELLA FUNZIONE? MAH
b) Fai un ciclo for da 0 a < m. (dove m è n/2). Nel blocco del for devi:
- mettere in una variabile temporanea vett[i] VA BENE e=vett[i] ???
- mettere in vett[i] il valore di vett[n-i-1] vett[i]=vett[n-i-1]
- mettere in vett[n-i-1] il valore temporaneo vett[n-i-1]=e
ho scritto in maiuscolo per non farti confondere con il tuo messaggio di prima
sarà sbagliato ma è questo quello che sono riusco a fare, quello che ho capito :)
void_inverti_vett_(int vett[], int n)
{
m=n/2;
for(i=0;i<m;i++){
i=vett[i];
vett[i]=vett[n-i-1];
vett[n-i-1]=i;}}
PER ESEMPIO POSSO FARE: m=n/2 ??? MA SI PUO INSERIRE UN'ALTRA VARIABILE ALL'INTERNO DELLA FUNZIONE? MAHMa certo!
Parti con questo:
void _inverti_vett_ (int vett[], int n)
{
int m = n/2;
....
}
P.S. devi proprio mettere un _ prima/dopo il nome della funzione???
bo, nella traccia li mette come li metto io gli '_'
ho scritto una cazzata?
void_inverti_vett_(int vett[], int n)
{
int m = n/2;
int i=0;
for(i=0;i<m;i++){
i=vett[i];
vett[i]=vett[n-i-1];
vett[n-i-1]=i;}
}
ho scritto una cazzata?
void_inverti_vett_(int vett[], int n)
{
int m = n/2;
int i=0;
for(i=0;i<m;i++){
i=vett[i];
vett[i]=vett[n-i-1];
vett[n-i-1]=i;}
}Quasi giusto. Devi dichiarare un'altra variabile per il valore temporaneo, non puoi usare 'i' sia per l'indice che per il valore temporaneo!!!
Metti 1 spazio a sx/dx del nome della funzione.
void_inverti_vett_(int vett[], int n)
{
int m = n/2;
int i=0;
int p=0;
for(i=0;i<m;i++){
p=vett[i];
vett[i]=vett[n-i-1];
vett[n-i-1]=i;}
}
è giusto cosi?
non ho capito quella cosa dello spazio
void_inverti_vett_(int vett[], int n)
{
int m = n/2;
int i=0;
int p=0;
for(i=0;i<m;i++){
p=vett[i];
vett[i]=vett[n-i-1];
vett[n-i-1]=i;}
}
è giusto cosi?Quaaaaaasi. La terza assegnazione hai lasciato 'i', metti 'p'. La prima inizializzazione di 'i' è superflua (la inizializzi nel for).
non ho capito quella cosa dello spazioti ho detto sx/dx ma il dx non c'entra. :p
L'importante è che void e il nome della funzione siano staccati.
:D void _inverti_vett_(int vett[], int n)
{
int m = n/2;
int i=0;
int p=0;
for(i=0;i<m;i++){
p=vett[i];
vett[i]=vett[n-i-1];
vett[n-i-1]=p;}
}
penso sia giusto e ti ringrazio per l'ennesima volta, casomani ci risentiamo a giorni per fare l'altro
grazie ancora, spero funzioni, mi fido.. :D
mi è scappata una faccina prima del void
vogliamo passare a questo "semplice" programmino
void _gen_labirinto_(char a[][]. int m, int n);
la funzione prende da input una matrice non inizializzata, e le sue dimensioni (m e n). Modifica i suoi elementi come segue: tramite un generatore pseudocasuale pone casualmente nelle varie posizioni della matrice o il carattere #(che indica che la posizione corrisponde a un pezzo di muro del labirinto) o il carattere .(che indica una posizione in cui si puo passare per uscire dal labirinto). La funzione stampa in output per righe la matrice cosi ottenuta. Il labirinto prodotto in outpute deve sempre essere risolubile: deve sempre esserci un percorso da una cella vuota nell'ultima riga in alto ad una cella vuota della riga in basso. la persona che esplora il labirinto si suppone che possa muoversi solo sulle celle vuote in orizzontale e verticale.
ad esempio se si ha in input una matrice composta da 10*10 elementi il programma dovrebbe riempire la matrice nel modo a sinistra. la soluzione del percorso è riportata a destra.
ASSUMIAMO CHE a[i][j] sia la cella della riga i e della colonna j.
Labirinto:
##.#..####
#...##..##
.#.##....#
#..###.###
##.#.#.#.#
#...#..###
#.#..#...#
##.#.#.#.#
#....#.#.#
###.#..###
Soluzione
##°#..####
#.°.##..##
.#°##....#
#.°###.###
##°#.#.#.#
#.°°#..###
#.#°°#...#
##.#°#.#.#
#...°#.#.#
###°#..###
sicuramente non sono allineati bene, ma basta che rendano l'idea
vogliamo passare a questo "semplice" programmino
void _gen_labirinto_(char a[][]. int m, int n);
[...]Questo, in effetti, è meno banale degli altri esercizi di prima ... ;)
Intanto ti dico subito che non puoi dichiarare il parametro come char a[][].
Se vuoi passare un array bidimensionale di char di dimensione "arbitraria", devi passare un puntatore char *a e poi gestire tu l'accesso alle celle sfruttando l'aritmetica dei puntatori.
vabbè questo lasciamolo alla fine, riprendiamo il primo esercizio:
tu hai scritto questo
1) Prendi la lunghezza della stringa s1:
int n1 = strlen (s1);
2) Il carattere nullo di s1 si trova in s1[n1]. Da lì in poi dovrai copiare s2.
3) Fai un ciclo for da 0 a < n. Nel blocco del for devi:
- Testare se s2[i] è nullo e in tal caso devi uscire dal for con un break.
- Copiare il carattere da s2[i] a s1[n1+i]
4) Finito il ciclo metti il nullo in s1[n1+i]
sono riuscito a fare questo
char *_strncat_(char *s1, const char *s2, in n)
{
int n1 = strlen (s1);
for(i=0;i<n;i++)
{
}
è giusto fino ad ora?
è giusto fino ad ora?Sì. Adesso prova a scrivere il codice nel blocco del for.
EDIT: e ricordati sempre di dichiarare le variabili. 'i' non l'hai dichiarata!!!
char *_strncat_(char *s1, const char *s2, in n)
{
int n1 = strlen (s1);
for(i=0;i<n;i++)
{
if(s2[i]=0){
break;}
s1[n1+i]=s2[i];
}
è sbagliato?
è sbagliato?È ok, salvo il fatto che devi dichiarare la 'i'.
Ora devi solo più mettere, dopo il ciclo for, il carattere nullo e poi restituire s1.
EDIT: oggi sono un po' sbadato ... hai fatto una assegnazione nel if!!! Devi mettere ==
char *_strncat_(char *s1, const char *s2, in n)
{
int i;
int n1 = strlen (s1);
for(i=0;i<n;i++)
{
if(s2[i]==0){
break;}
s1[n1+i]=s2[i];
}
come si fa a mettere il carattere nullo, cioè che significa. e anche restituire s1
come si fa a mettere il carattere nullo, cioè che significa. e anche restituire s1Il carattere nullo è '\0' (che poi è la stessa cosa di 0, ma è più chiaro, secondo me). Quindi devi mettere il nullo come ho spiegato più sopra.
Poi prima della fine della funzione, devi fare un return di s1.
char *_strncat_(char *s1, const char *s2, in n)
{
int i;
int n1 = strlen (s1);
for(i=0;i<n;i++)
{
if(s2[i]==0){
break;}
s1[n1+i]=s2[i];
}
'\0'
return s1;
}
si ma il carattere nullo dove lo devo mettere
si ma il carattere nullo dove lo devo mettere4) Finito il ciclo metti il nullo in s1[n1+i]
char *_strncat_(char *s1, const char *s2, in n)
{
int i;
int n1 = strlen (s1);
for(i=0;i<n;i++)
{
if(s2[i]==0){
break;}
s1[n1+i]=s2[i];
}
s1[n1+i]='\0';
return s1;
}
è sbagliato al 100% sta cosa del nullo, il resto però è giusto?
è sbagliato al 100% sta cosa del nullo, il resto però è giusto?Ora è tutto giusto. :)
sperando che funzioni ti ringrazio ancora, alla prossima
sperando che funzioni ti ringrazio ancora, alla prossimaMa non hai un compilatore per fare qualche prova? :confused:
certo che ce l'ho, ma la funzione senza programma non la posso provare, o no?
cioè mica posso scriverci la funzione direttamente e soltanto, che risultato mi darebbe
Semplice programmino per la prova:
#include <stdio.h>
#include <string.h>
char *_strncat_ (char *s1, const char *s2, int n)
{
int i;
int n1 = strlen (s1);
for (i = 0; i < n; i++)
{
if (s2[i] == 0)
break;
s1[n1+i] = s2[i];
}
s1[n1+i] = '\0';
return s1;
}
int main (void)
{
char buf[80];
strcpy (buf, "ciao ");
printf ("[%s]\n", _strncat_ (buf, "prova", 20));
strcpy (buf, "ciao ");
printf ("[%s]\n", _strncat_ (buf, "prova", 3));
return 0;
}Testa i 2 casi in cui 'n' è maggiore/minore di s2.
comq quello che mi chiede l'esercizio è solo di scrivere la funzione giusto?
comq quello che mi chiede l'esercizio è solo di scrivere la funzione giusto?Sì, ma se vuoi provarla, devi almeno fare un programmino con un main(), no?
riprendiamo questo semplice programmino
Si scriva una funzione
char*_strncat_(char*s1, const char*s2, int n);
tale funzione appende al massimo n caratteri della stringa s2 allafine della stringa s1. In particolare appende a s1 n caratteri di s2 se s2 contiene n caratteri validi, il numero di caratteri validi di s2 altrimenti. Il primo carattere di s2 va a sovrascrivere il carattere '\0' di terminazione della stringa s1. Una volta appesi i caratteri di s2 a s1 si dovra terminare la stringa s1 cosi modificata con un carattere di fine stringa. La funzione strncat restituisce un puntatore alla stringa s1 cosi modificata.
Esempio: se s1 è la stringa pippo
s2 è la stringa pluto e n vale 20
la funzione restituirà un puntatore a s1 modificata in modo da contenere pippopluto
se s1 è la stringa pippo
s2 è la stringa pluto e n vale 0
la funzione restituirà un puntatore a s1 modificata in modo da contenere pippo
se s1 è la stringa pippo
s2 è la stringa pluto e n vale 3
la funzione restituirà un puntatore a s1 modificata in modo da contenere pippoplu
i passi da seguire?
i passi da seguire?Ma ... scusa, il sorgente completo per un test l'ho pure postato! Prendi il sorgente del mio post #48 e gli modifichi/aggiungi i test nel main.
ma che esercizio è questo?
#include <stdio.h>
#include <string.h>
char *_strncat_ (char *s1, const char *s2, int n)
{
int i;
int n1 = strlen (s1);
for (i = 0; i < n; i++)
{
if (s2[i] == 0)
break;
s1[n1+i] = s2[i];
}
s1[n1+i] = '\0';
return s1;
}
int main (void)
{
char buf[80];
strcpy (buf, "ciao ");
printf ("[%s]\n", _strncat_ (buf, "prova", 20));
strcpy (buf, "ciao ");
printf ("[%s]\n", _strncat_ (buf, "prova", 3));
return 0;
}
a me serve di fare questa funzione, cosa c'entra quello che mi hai indicato tu nel post #48?
Si scriva una funzione
char*_strncat_(char*s1, const char*s2, int n);
tale funzione appende al massimo n caratteri della stringa s2 allafine della stringa s1. In particolare appende a s1 n caratteri di s2 se s2 contiene n caratteri validi, il numero di caratteri validi di s2 altrimenti. Il primo carattere di s2 va a sovrascrivere il carattere '\0' di terminazione della stringa s1. Una volta appesi i caratteri di s2 a s1 si dovra terminare la stringa s1 cosi modificata con un carattere di fine stringa. La funzione strncat restituisce un puntatore alla stringa s1 cosi modificata.
Esempio: se s1 è la stringa pippo
s2 è la stringa pluto e n vale 20
la funzione restituirà un puntatore a s1 modificata in modo da contenere pippopluto
se s1 è la stringa pippo
s2 è la stringa pluto e n vale 0
la funzione restituirà un puntatore a s1 modificata in modo da contenere pippo
se s1 è la stringa pippo
s2 è la stringa pluto e n vale 3
la funzione restituirà un puntatore a s1 modificata in modo da contenere pippoplu
a me serve di fare questa funzioneEhm .... allora: la funzione l'hai già scritta tu completa e corretta nel tuo post #42. Se vuoi testarla realmente con un compilatore c'è il mio esempio di test nel post #48.
Cioè ... non ho capito: che cosa ti manca o ti serve ancora??
cazzo, c'hai ragione :D :D :D
ho sbagliato esercizio, un attimo che ne metto n'altro :)
Si scriva una funzione
int _strcspn_(const char *s1, const char *s2);
che determine la lunghezza del prefisso piu lungo di s1 che consista solo di caratteri contenuti in s2.
si scriva anche una seconda versione della funzione il cui prototipo sia:
int _strcspn_VETT_(char s1[], char s2[]);
che svogla esattamente lo stesso compito di strcspn. Obiettivo dell'esercizo nel farvi consegnare due versioni della funzione e di farvi usare due notazioni diverse (con o senza puntatori) per lavorare sulle stringhe.
se s1 è la stringa
aprtyui
ed s2 è la stringa
qrty
allora il prefisso di s1 contiene caratteri di s2 ha lunghezza 0 (la prima lettera di s1 non compare in s2)
Si scriva una funzione
int _strcspn_(const char *s1, const char *s2);
che determine la lunghezza del prefisso piu lungo di s1 che consista solo di caratteri contenuti in s2.
si scriva anche una seconda versione della funzione il cui prototipo sia:
int _strcspn_VETT_(char s1[], char s2[]);
che svogla esattamente lo stesso compito di strcspn. Obiettivo dell'esercizo nel farvi consegnare due versioni della funzione e di farvi usare due notazioni diverse (con o senza puntatori) per lavorare sulle stringhe.Alcune cose:
1) L'esercizio è tutto sommato abbastanza semplice. Segui questo schema:
- Metti una variabile che tiene la lunghezza del prefisso da calcolare, es 'lung' inizialmente a 0.
- Prendi 1 carattere per volta di s1, andando in avanti, fino al nullo (escluso).
- Per ogni carattere di s1, scansioni la stringa s2 per vedere se il carattere vi è contenuto. Se lo trovi, incrementi 'lung' e continui con il prossimo carattere di s1. Ma se non lo trovi, vuol dire che il prefisso è terminato e quindi termini il tutto.
- Alla fine fai ritornare 'lung'.
2) Ti è stato chiesto di fare 2 versioni: una con puntatori e una con i vettori. E questo può anche essere ok. Però chi ti ha dato l'esercizio non deve essere un gran genio di "C". Perché dichiarare come parametro char *s1 oppure char s1[] è la stessa identica cosa: alla funzione viene sempre passato comunque un puntatore!!!
Quindi accedere alle 2 stringhe s1/s2 tramite l'indicizzazione s1[i] oppure tramite dereferenziazione del puntatore *s1 (o meglio con la formula generica *(s1+i) ) sostanzialmente è la stessa cosa e non c'entra nulla con il fatto di dichiarare il parametro in un modo o nell'altro.
- Prendi 1 carattere per volta di s1, andando in avanti, fino al nullo (escluso).
- Per ogni carattere di s1, scansioni la stringa s2 per vedere se il carattere vi è contenuto. Se lo trovi, incrementi 'lung' e continui con il prossimo carattere di s1. Ma se non lo trovi, vuol dire che il prefisso è terminato e quindi termini il tutto.
devo usare il for o while. se uso il for però che ci metto dentro?
io avevo pensato a una cosa tipo while(s1!='\0')
devo usare il for o while. se uso il for però che ci metto dentro?
io avevo pensato a una cosa tipo while(s1!='\0')Per essere più chiari, la scansione di una stringa la puoi fare in due modi:
Dato un char *str:
a)
int i, n = strlen (str);
for (i=0; i<n; i++)
{
... accedi al carattere con str[i] ...
}
b)
while (*str != '\0')
{
... accedi al carattere con *str ...
str++;
}
- Per ogni carattere di s1, scansioni la stringa s2 per vedere se il carattere vi è contenuto. Se lo trovi, incrementi 'lung' e continui con il prossimo carattere di s1. Ma se non lo trovi, vuol dire che il prefisso è terminato e quindi termini il tutto.
questo pezzo come si fa
int _strcspn_(const char *s1, const char *s1)
{
lung = 0;
int i, n = strlen (str);
for (i=0; i<n; i++)
{
- Per ogni carattere di s1, scansioni la stringa s2 per vedere se il carattere vi è contenuto. Se lo trovi, incrementi 'lung' e continui con il prossimo carattere di s1. Ma se non lo trovi, vuol dire che il prefisso è terminato e quindi termini il tutto.
questo pezzo come si faSe vuoi farlo con l'indicizzazione:
- Prendi con strlen la lunghezza delle 2 stringhe s1/s2 (avrai n1 e n2).
- Fai un ciclo for principale per scansionare s1.
- Fai un ciclo for annidato per scansionare s2 (e in cui compari s1[i] con s2[k]).
Se vuoi farlo tramite dereferenziazione:
- Devi dichiarare un puntatore char *t perché non devi alterare s2.
- Fai un while (*s1 != '\0') per scansionare s1
- Metti s2 in t e poi fai un ciclo interno while (*t != '\0') (e in cui compari *s1 con *t)
Come vedi sono molto simili.
io voglio continuare questo, come si fa
int _strcspn_(const char *s1, const char *s1)
{
lung = 0;
int i, n = strlen (str);
for (i=0; i<n; i++)
{
io voglio continuare questo, come si fa
int _strcspn_(const char *s1, const char *s1)
{
lung = 0;
int i, n = strlen (str);
for (i=0; i<n; i++)
{All'inizio devi prendere la lunghezza delle due stringhe, in modo da averle in n1 e n2. Dovrai anche mettere 2 variabili per gli indici, chiamale i e j, per esempio. E dovrai anche avere una variabile es. 'trovato' che fa da flag che indica se il carattere è stato trovato o meno.
Fai il primo ciclo for per scansionare s1 (l'hai appena abbozzato).
Dentro questo ciclo fai:
Metti 'trovato' a 0.
Fai un secondo ciclo for per scansionare s2.
Dentro questo ciclo fai:
Compari s1[i] con s2[j]. Se sono uguali metti 'trovato' a 1, incrementi 'lung' ed esci con break.
Se 'trovato' è 0, esci con break.
è inutile, non so come si fa a scansionare, e quando dici quella cosa di n1 e n2, a parole le capisco ma non so proprio cosa scriverci
parto da questo
int _strcspn_(const char *s1, const char *s1)
{
lung = 0;
int i, n = strlen (str);
int trovato = 0;
for (i=0; i<n; i++)
{
è inutile, non so come si fa a scansionareÈ solo per dire che della stringa prendi ogni singolo carattere per volta! Il for serve per andare da 0 a n-1. Dentro il for prendi il carattere con s[indice]. Tutto qui.
e quando dici quella cosa di n1 e n2, a parole le capisco ma non so proprio cosa scriverci.Hai scritto
n = strlen (str);
giusto??
Ne devi fare 2, una strlen per prendere la lunghezza di s1 e un'altra strlen per prendere la lunghezza di s2.
ho provato a fare questo
int _strcspn_(const char *s1, const char *s1)
{
lung = 0;
int i;
int j;
int n1 = strlen (str);
int n2 = strlen (str);
int trovato = 0;
for (i=0; i<n1; i++)
{
trovato = 0;
s1[i];
for(j=0;j<n2;j++)
{
if(s1[i]==s2[j]){
trovato = 1;
++ lung;
break;
}
if(trovato=0)
break;
}}
ho provato a fare questo
int _strcspn_(const char *s1, const char *s1) /* metti s2 nel secondo */
{
lung = 0; /* devi mettere int */
int i;
int j;
int n1 = strlen (str); /* metti s1 */
int n2 = strlen (str); /* metti s2 */
int trovato = 0;
for (i=0; i<n1; i++)
{
trovato = 0;
s1[i]; /* non serve a una mazza */
for(j=0;j<n2;j++)
{
if(s1[i]==s2[j]){
trovato = 1;
++ lung;
break;
}
if(trovato=0)
break; /* devi farlo nel ciclo principale, non in quello annidato
}}In rosso è segnato quello che non va.
int _strcspn_(const char *s1, const char *s2)
{
int lung = 0;
int i;
int j;
int n1 = strlen (s1);
int n2 = strlen (s2);
int trovato = 0;
for (i=0; i<n1; i++)
{
trovato = 0;
s1[i];
for(j=0;j<n2;j++)
{
if(s1[i]==s2[j]){
trovato = 1;
++ lung;
break;
}}
if(trovato=0)
break;}
è perfetto??? dimmi di si :D
io devo scappa
fammi sape se è giusto
grazie
ciao
è perfetto??? dimmi di si :DQuaaaasi.
Nell'ultimo if hai fatto una assegnazione (devi mettere ==).
Completalo facendo ritornare lung e chiudendo con }
int _strcspn_(const char *s1, const char *s2)
{
int lung = 0;
int i;
int j;
int n1 = strlen (s1);
int n2 = strlen (s2);
int trovato = 0;
for (i=0; i<n1; i++)
{
trovato = 0;
s1[i];
for(j=0;j<n2;j++)
{
if(s1[i]==s2[j]){
trovato = 1;
++ lung;
break;
}}
if(trovato==0)
break;}
return lung;
}
giusto??
giusto??Sì. Ma togli quel s1[i]; che non serve a nulla.
Penultimo esercizio:
Si scriva una funzione
int _strch2_(const char*s, in c);
La funzione strch2 calcola e restituisce il numero massimo di occorrenze consecutive del carattere c in s.
Ad esempio se la stringa s contiene
arttoptttwe
e c è il carattere t, la funzione restituirà 3(ci sono due seguenze di t che compaiono nella stringa, tt e ttt, quella piu lunga vede t ripetersi 3 volte).
Ad esempio se la stringa s contiene
arttoptttwe
e c è il carattere p, la funzione restituirà 1(p occorre una sola volta, numero di occorrenze consecutive 1)
Ad esempio se la stringa s contiene
arttoptttwe
e c è il carattere u, la funzione restituirà 0(u non occorre nella stringa)
Penultimo esercizio:
Si scriva una funzione
int _strch2_(const char*s, in c);
La funzione strch2 calcola e restituisce il numero massimo di occorrenze consecutive del carattere c in s.Non è difficile neanche questo.
Devi innanzitutto avere 2 variabili che fanno da contatore, chiamiamole 'lung' e 'lung_max'. Il motivo è semplice: ti può capitare il caso della stringa "arttttopttwe" dove ci sono prima 4 't' e poi dopo 2 't'. In questo caso non devi prendere l'ultima lunghezza (2) ma sempre quella massima (4).
Entrambe le variabili devono essere inizialmente a 0.
Devi naturalmente scansionare tutta la stringa. Puoi fare il solito ciclo for (ma devi usare strlen per conoscere la lunghezza della stringa) oppure, meglio ancora, usi il puntatore 's' per accedere al carattere (con *s) e quindi incrementi 's'. Vedi tu cosa fare.
A parte la questione di come accedere ai caratteri, devi fare pochi test molto semplici. Stavolta prova a pensarci un momento tu, poi se hai problemi, vediamo. Ti assicuro che non è complicato, basta solo ragionarci un pochino.
Devi prestare attenzione ad un caso particolare: quando il carattere ricercato si trova al fondo della stringa.
è giusto questo?
ora però come si procede
int _strch2_(const char *s, int c)
{
int lung=0;
int lung_max=0;
int n1 = strlen (s1);
for(i=0;i<n1;i++){
è giusto questo? Sì, fin qui è corretto.
ora però come si procedeAllora prova a pensare e a rispondere a queste domande:
a) Quando trovi il carattere richiesto, cosa si dovrebbe fare? Devi ovviamente incrementare un contatore, quale?
b) Quando trovi un carattere che non è quello richiesto, cosa si dovrebbe fare?? Se il carattere precedente era quello richiesto, dovrai fare qualcosa, altrimenti nulla.
non ci riesco proprio, non è che puoi spiegarmelo come facevi con gli altri esercizi? la riuscivo a capirci qualcosa
comq adesso devo andare, torno stasera
ciao
Andrea16v
16-11-2006, 10:37
Meglio di CEPU... :sofico:
non ci riesco proprio, non è che puoi spiegarmelo come facevi con gli altri esercizi? la riuscivo a capirci qualcosaAllora guarda questo schemino:
ricerca di 't':
a r t t t t o p t t w e
lung 0 0 1 2 3 4 0 0 1 2 0 0
lung_max 0 0 0 0 0 0 4 4 4 4 4 4Questo è lo schema "temporale" che mostra i valori che dovrebbero avere lung e lung_max man mano che si esaminano i caratteri nella stringa in esempio.
Ti è più chiaro, così??
int _strch2_(const char *s, int c)
{
int lung=0;
int lung_max=0;
int n1 = strlen (s1);
for(i=0;i<n1;i++){
sono arrivato qui, ora puoi scrivermi a parole come si continua, come per gli altri esercizi e io lo traduco in C???
altrimenti non capisco, tanto sti esercizi non li uso molto per imparare a programmare, per imparare uso quelli del libro con le soluzioni
altrimenti non capisco, tanto sti esercizi non li uso molto per imparare a programmare, per imparare uso quelli del libro con le soluzioniAh beh .... allora .... :nono:
Se vuoi imparare a programmare ... devi imparare a ragionare!
Intanto mi è venuto in mente che, in effetti, ci sono 2 modi di gestire l'aggiornamento della variabile 'lung_max'. E uno è un po' più semplice dell'altro.
Modo 1:
ricerca di 't':
a r t t t t o p t t w e
lung 0 0 1 2 3 4 0 0 1 2 0 0
lung_max 0 0 0 0 0 0 4 4 4 4 4 4
Modo 2 (più semplice):
ricerca di 't':
a r t t t t o p t t w e
lung 0 0 1 2 3 4 0 0 1 2 0 0
lung_max 0 0 1 2 3 4 4 4 4 4 4 4Forse è meglio se usi quest'ultimo che è più semplice.
Cosa puoi notare da quest'ultimo schemino?? Diverse cose:
a) Ogni volta che trovi il carattere richiesto, devi incrementare 'lung'.
b) Ogni volta che non trovi il carattere richiesto, devi azzerare 'lung'.
c) La variabile 'lung_max' la devi aggiornare quando 'lung' è maggiore di 'lung_max'.
c'ho provato ma sarà sbagliatissimo
int _strch2_(const char *s, int c)
{
int lung=0;
int lung_max=0;
int n1 = strlen (s1);
for(i=0;i<n1;i++){
if(s1[i]==s1[i++]){
++lung;}
else{
lung=0;}
if(lung_max<lung){
lung=lung_max;}
c'ho provato ma sarà sbagliatissimo
int _strch2_(const char *s, int c)
{
int lung=0;
int lung_max=0;
int n1 = strlen (s1);
for(i=0;i<n1;i++){
if(s1[i]==s1[i++]){
++lung;}
else{
lung=0;}
if(lung_max<lung){
lung=lung_max;}Infatti non va per niente bene. Non devi verificare se 2 caratteri qualunque sono adiacenti, ma devi verificare se un certo carattere ben preciso si trova ripetuto in modo consecutivo e determinare quale è la sequenza più lunga.
Ripeto (anche se l'ho spiegato prima):
Se il carattere è uguale a quello richiesto, incrementi 'lung'. Inoltre se 'lung' è maggiore di 'lung_max' allora aggiorni 'lung_max'.
Se il carattere non è uguale a quello richiesto, azzeri 'lung'.
Infatti non va per niente bene. Non devi verificare se 2 caratteri qualunque sono adiacenti, ma devi verificare se un certo carattere ben preciso si trova ripetuto in modo consecutivo e determinare quale è la sequenza più lunga.
UN AIUTINO?? :D
il mio punto di partenza è sempre questo
int _strch2_(const char *s, int c)
{
int lung=0;
int lung_max=0;
int n1 = strlen (s1);
for(i=0;i<n1;i++){
UN AIUTINO?? :D Sono poi 2 if da fare!
Se s[i] è uguale a c, allora incrementi 'lung' e se è maggiore di 'lung_max', aggiorni 'lung_max'. Altrimenti azzeri 'lung'.
int _strch2_(const char *s, int c)
{
int lung=0;
int lung_max=0;
int n1 = strlen (s1);
for(i=0;i<n1;i++){
if(s[i]==c)
{
++lung;
if(lung>lung_max){
lung_max=lung;}}
else{
lung=0;}}
ci siamo ora?
perdonami andbin, ma come mai ancora non mi hai mandato a quel paese? :)
ci siamo ora?Ok, ci siamo!!!
Solo alcune bazzeccole:
- Il parametro è 's', in strlen hai usato s1
- Ti è stato richiesto espressamente di passare int c?? Sarebbe meglio char c
- fai ritornare lung_max e chiudi la func.
perdonami andbin, ma come mai ancora non mi hai mandato a quel paese? :)Non mi permetterei mai. :)
int _strch2_(const char *s, char c)
{
int lung=0;
int lung_max=0;
int n1 = strlen (s);
for(i=0;i<n1;i++){
if(s[i]==c)
{
++lung;
if(lung>lung_max){
lung_max=lung;}}
else{
lung=0;}
return lung_max;
}
è buona ora?
ti ringrazio di tutto, ciao
è buona ora?Manca la graffa di chiusura del for. Cerca di scrivere il sorgente in modo chiaro con una corretta spaziatura e indentazione. Scopriresti subito dove mancano le graffe!
ora va bene?
int _strch2_(const char *s, char c)
{
int lung=0;
int lung_max=0;
int n1 = strlen (s);
for(i=0;i<n1;i++){
if(s[i]==c)
{
++lung;
if(lung>lung_max){
lung_max=lung;}}
else{
lung=0;}
return lung_max;}
}
comq solo quando incollo sul forum non ci sono gli spazi, sennò quando uso il compilatore li metto ovunque. invece quando lo posto qui mi mette tutto appiccicato
ora va bene?No la graffa va prima del return!
invece quando lo posto qui mi mette tutto appiccicatoDevi metterlo tra i tag CODE (è il # tra gli strumenti).
Così si scrive:
int _strch2_(const char *s, char c)
{
int lung=0;
int lung_max=0;
int n1 = strlen (s);
for(i=0;i<n1;i++) {
if(s[i]==c) {
++lung;
if(lung>lung_max) {
lung_max=lung;
}
}
else {
lung=0;
}
}
return lung_max;
}A me personalmente non piacciono le graffe di apertura messe al fondo dopo l'istruzione .... ma le accetto lo stesso.
E' L'ULTIMO
void _gen_labirinto_(char a[][]. int m, int n);
la funzione prende da input una matrice non inizializzata, e le sue dimensioni (m e n). Modifica i suoi elementi come segue: tramite un generatore pseudocasuale pone casualmente nelle varie posizioni della matrice o il carattere #(che indica che la posizione corrisponde a un pezzo di muro del labirinto) o il carattere .(che indica una posizione in cui si puo passare per uscire dal labirinto). La funzione stampa in output per righe la matrice cosi ottenuta. Il labirinto prodotto in outpute deve sempre essere risolubile: deve sempre esserci un percorso da una cella vuota nell'ultima riga in alto ad una cella vuota della riga in basso. la persona che esplora il labirinto si suppone che possa muoversi solo sulle celle vuote in orizzontale e verticale.
ad esempio se si ha in input una matrice composta da 10*10 elementi il programma dovrebbe riempire la matrice nel modo a sinistra. la soluzione del percorso è riportata a destra.
ASSUMIAMO CHE a[i][j] sia la cella della riga i e della colonna j.
Labirinto:
##.#..####
#...##..##
.#.##....#
#..###.###
##.#.#.#.#
#...#..###
#.#..#...#
##.#.#.#.#
#....#.#.#
###.#..###
Soluzione
##°#..####
#.°.##..##
.#°##....#
#.°###.###
##°#.#.#.#
#.°°#..###
#.#°°#...#
##.#°#.#.#
#...°#.#.#
###°#..###
sicuramente non sono allineati bene, ma basta che rendano l'idea
void _gen_labirinto_(char a[][]. int m, int n);Ok, come avevo già detto in questo thread, se vuoi passare una matrice bidimensionale di dimensione "arbitraria" non puoi dichiarare il parametro come char a[][].
A parte questo, il problema è da suddividere in 2 fasi:
1) Creazione del labirinto
2) Soluzione del labirinto
Per la creazione c'è il problema che generandolo in modo casuale, non è detto che si ottenga un labirinto percorribile secondo le richieste. Si possono comunque fare più tentativi fino a quando non si trova un labirinto risolvibile.
Per la soluzione del labirinto, bisogna valutare come ci si può muovere all'interno del labirinto. La prima cosa che mi viene in mente: l'ipotetica persona che esplora il labirinto deve viaggiare sempre e solo nella direzione dell'uscita o può anche eventualmente passare per una strada che "torna indietro"???
non lo so, io so quello che sai tu,perchè il testo l'ho copiato e incollato, non me l'hanno spiegato
sembra abbastanza difficile però
sembra abbastanza difficile peròDifficilissimo no, semmai si può dire che non è come gli altri esercizi precedenti in cui te la cavavi con una unica semplice funzioncina.
Per questo esercizio è bene mettere giù diverse funzioni più il main.
vabbè lo salto questo, non fa niente
Per la creazione c'è il problema che generandolo in modo casuale, non è detto che si ottenga un labirinto percorribile secondo le richieste. Si possono comunque fare più tentativi fino a quando non si trova un labirinto risolvibile.anziche' crearlo in modo casuale, è meglio imho fare cosi':
mettiamo il caso che la matrice sia di 30 righe x 10 colonne
si genera un numero random da 0 a 9 (n) e si rende percorribile mat[0][n]
matrice[0][n]='.'
si genera un numero random da 1 a 3:
se il numero è 1 e non ci si trova sul bordo sinistro
si va a sinistra (mat[0][n-1]='.')
altrimenti
si genera un altro numero random e si ripete
se è 2
se ci si trova alla fine
si esce dal ciclo
altrimenti
si va giu (mat[1][n]='.')
se è 3 e non ci si trova sul bordo destro
si va a destra (mat[0][n+1])
altrimenti
si genera un altro numero random e si ripete.
ora vado a provare :)
io non ci riuscirei mai, se magari ti diverti a farlo poi puoi postarlo..
io non ci riuscirei mai
in cosa trovi difficolta' di preciso? nel tradurre il ragionamento in codice?
no, proprio nel fare il ragionamento, per pensare alla soluzione
no, proprio nel fare il ragionamento, per pensare alla soluzione
mentre ragioni per scrivere un programma, devi ricordare che il computer fa solo ed esattamente cio' che gli dici, e solo se glielo dici nel suo linguaggio.
per fare un ragionamento che sia vicino a quello del computer, cerca di elencare tutte le operazioni che faresti per, ad esempio, capire qual è il numero piu' grande fra 3 numeri:
se il primo numero è piu grande del secondo e il primo numero è piu' grande del terzo
allora
il primo numero è il piu grande
e poi tradurle:
if(n1>n2&&n1>n3)
{
PiuGrande=n1;
}
a questi esercizi ci arriva, ma quello del labirinto è molto piu complicato
a questi esercizi ci arriva, ma quello del labirinto è molto piu complicato
proviamo ;)
#include <stdio.h>
#include <time.h>//per usare rand
void generalabirinto(int** matrice, int x, int y);//prototipo
int main()
{
srand(time(NULL));//il seme per generare numeri random
int matrice[10][30];
for(int i=0;i<10;i++)
for(int j=0;j<30;j++)
matrice[i][j]='#';//impostiamo tutto il labirinto come non percorribile
generalabirinto(matrice,10,30);
return 0;
}
void generalabirinto(int** matrice, int x, int y) //eccoci :)
{
si genera un numero random da 0 a y
scrivendo il codice ho pensato di usare due interi: xpos e ypos:
int ypos=rand()%y,xpos=0;
si rende percorribile mat[0][ypos]
matrice[xpos][ypos]='.';
ora un ciclo infinito
for(;;)
{
si genera un numero random da 1 a 3
int num=rand()%3+1;
se il numero è 1 e non ci si trova sul bordo sinistro
if(num==1&&ypos!=1)
si va a sinistra
ypos--;
altrimenti
else
si ripete
continue;
se è 2
if(num==2)
se ci si trova sopra la fine
if(xpos==x-1)
si esce dal ciclo
break
altrimenti
else
si va giu
xpos--;
se è 3 e non ci si trova sul bordo destro
if(num==3&&ypos<y-1)
si va a destra
ypos++
altrimenti
else
si ripete
continue;
poi bisogna rendere transitabile la posizione corrente:
matrice[xpos][ypos]='.';
e si chiudono il ciclo e la funzione
}
}
la funzione, semplificata:
void generalabirinto(int** mat,int x, int y)
{
int ypos=rand()%y,xpos=0;
int chesifa;
mat[xpos][ypos]='.';
for(;;)
{
chesifa=rand()%3+1;
switch(chesifa)
{
case 1://y-1
if(ypos-1>=0)
mat[xpos][--ypos]='.';
break;
case 2://x+1
if(xpos+1<x)
mat[++xpos][ypos]='.';
else
exit(0);
break;
case 3://y+1
if(ypos+1<y)
mat[xpos][++ypos]='.';
break;
}
}
}
edit: ho da fare per una mezz'oretta... quando finisco torno :)
ti ringrazio enormemente
basta che poi mi dici qual'è la versione definitiva della funzione
grazie ancora
void generalabirinto(int** matrice, int x, int y);//prototipo
int main()
{
srand(time(NULL));//il seme per generare numeri random
int matrice[10][30];Alt!! Non va bene!
Una variabile come int** matrice è totalmente incompatibile con l'array bidimensionale che hai dichiarato nel main (int matrice[10][30]).
Cioè non sono assolutamente la stessa cosa.
Alt!! Non va bene!
Una variabile come int** matrice è totalmente incompatibile con l'array bidimensionale che hai dichiarato nel main (int matrice[10][30]).
Cioè non sono assolutamente la stessa cosa.
:mc: ah... :doh: e come si passa un array bidimensionale a una funzione :confused:
:mc: ah... :doh: e come si passa un array bidimensionale a una funzione :confused:La questione è sempre quella di stabilire se si vuole fare una cosa "generica" oppure no.
In questo caso si vuole realizzare una funzione a cui passare una matrice di dimensioni "arbitrarie" passando anche il numero di righe/colonne.
Se si ha un array "classico" bidimensionale del tipo char mat[10][20] e lo si vuole passare in maniera "generica", si deve fare così:
void funzione (char *matrice, int righe, int colonne)
{
/* Si accede con matrice[r * colonne + c] */
}
...
char mat[10][20];
funzione (&mat[0][0], 10, 20);
...
potete scrivermi una versione definitiva della funziona, visto che ormai il grosso è fatto
La questione è sempre quella di stabilire se si vuole fare una cosa "generica" oppure no.
In questo caso si vuole realizzare una funzione a cui passare una matrice di dimensioni "arbitrarie" passando anche il numero di righe/colonne.
Se si ha un array "classico" bidimensionale del tipo char mat[10][20] e lo si vuole passare in maniera "generica", si deve fare così:
void funzione (char *matrice, int righe, int colonne)
{
/* Si accede con matrice[r * colonne + c] */
}
...
char mat[10][20];
funzione (&mat[0][0], 10, 20);
...
forse sarebbe meglio dichiarare la matrice fuori dal main in modo da non doverla passare alla funzione...
o se poi l'esercizio richiede il passaggio della matrice come parametro, allora..
qualcuno puo scrivermi una versione definitiva della funzione, visto che ormai è quasi fatta
grazie
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.