seneca · 29/08/2007 17:53 · #1Questo programma (corretto e funzionante) prende una frase (preimpostata) e restituisce in output la frase senza le s.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * cancella(char *str, char c)
{
int i, j=0;
char *app;
app=(char*) malloc(strlen(str)+1);
for (i=0; i<= strlen(str); ++i)
if (str[i]!=c)
app[j++]=str[i];
str=(char*) malloc(strlen(app)+1);
strcpy(str, app);
free(app);
return str;
}
main()
{
char *s="sschissa se ss s sfunzionassssss";
printf("La frase da esaminare è: %s\n", s);
printf("%s\n", cancella(s, 's'));
}
Qui ho provato a cambiare il main per permettere di personalizzare la frase prendendola in input da tastiera, ma non riesco a trovare il bandolo della matassa perchè va sempre in segmentation fault. Dove sbaglio?
main()
{
char *x;
char y[100];
char *a="s", *b="n";
char *s="sschissa se ss s sfunzionassssss";
printf("La frase da esaminare è: %s\n", s);
printf("Vuoi cambiare la frase? s/n\n");
scanf("%s", x);
if (strcmp(x, b)==0)
printf("%s\n", cancella(s, 's'));
else if (strcmp(x, a)==0)
{
printf("Scrivi la nuova frase:\n");
gets(y);
printf("%s\n", cancella(y, 's'));
}
else
printf("Opzione non valida\n");
} morpheus · 29/08/2007 18:17 · #2A parte alcune scelte discutibili, gli errori (IMO) *seri* che hai commesso sono in definitiva questi:
- scanf su puntatore non inizializzato
- uso di strcmp
- uso di strcpy
- uso di gets
La 1 è sicuramente quella che ti bomba l'app, per le altre ti rimando alle relative manpages per capire perché NON vanno usate.
Bye,
M.
seneca · 29/08/2007 19:06 · #3morpheus ha scritto:A parte alcune scelte discutibili, gli errori (IMO) *seri* che hai commesso sono in definitiva questi:
- scanf su puntatore non inizializzato
- uso di gets
- uso di strcpy
- uso di strcmp
La 1 è sicuramente quella che ti bomba l'app, per le altre ti rimando alle relative manpages per capire perché NON vanno usate.
Ti ringrazio anzitutto per la risposta. Ti rispondo per punti:
- ottimo suggerimento, ma ero convinto erroneamente che si potesse fare; penso che ora lo avrò bene in testa! infatti il programma ora prosegue fino all'esecuzione di gets
- scanf prende in input una parola, quando incontra lo spazio termina; ho letto che gets è sconsigliata per il non controllo della grandezza della variabile in cui si va a memorizzare il valore, ma allora che devo usare per prendere in input una frase (comprensiva di spazi)? non ho trovato alternative... aggiungo che mettendo scanf e inserendo UNA sola parola il programma funziona, mettendo gets non mi fa inserire nulla e restituisce ovviamente stringa nulla
- l'esercizio base l'ho preso da un testo universitario, quindi se va bene al prof strcpy. per ora va bene pure a me; sicuramente avrò modo di approfondire ma ora, come avrai capito, sono alle prime armi
- anche qui, ho fatto ricerche su ricerche, ma non ho trovato soluzioni migliori per comparare due stringhe...
Se riuscissi a darmi una mano, te ne sarei molto grato...
Ciao!
morpheus · 29/08/2007 19:39 · #4seneca ha scritto:scanf prende in input una parola, quando incontra lo spazio termina; ho letto che gets è sconsigliata per il non controllo della grandezza della variabile in cui si va a memorizzare il valore, ma allora che devo usare per prendere in input una frase (comprensiva di spazi)? non ho trovato alternative... aggiungo che mettendo scanf e inserendo UNA sola parola il programma funziona, mettendo gets non mi fa inserire nulla e restituisce ovviamente stringa nulla
Una soluzione abbastanza cruda potrebbe essere definire un array di (toh) 512 char e leggere AL MASSIMO 511 char da terminale. In ogni caso, devi stabilire un limite superiore alla dimensione della stringa.
seneca ha scritto:l'esercizio base l'ho preso da un testo universitario, quindi se va bene al prof strcpy. per ora va bene pure a me; sicuramente avrò modo di approfondire ma ora, come avrai capito, sono alle prime armi
strcpy non prevede un limite superiore, copia dal primo char al null finale della stringa di partenza senza preoccuparsi che nell'array di destinazione ci sia spazio sufficiente. Usa strncpy.
seneca ha scritto:anche qui, ho fatto ricerche su ricerche, ma non ho trovato soluzioni migliori per comparare due stringhe...
Alla fine puoi sempre usare strcmp al posto di strncmp, ma personalmente preferisco usare la seconda (almeno so qual'è il numero massimo di iterazioni).
seneca · 29/08/2007 23:42 · #5morpheus ha scritto:Una soluzione abbastanza cruda potrebbe essere definire un array di (toh) 512 char e leggere AL MASSIMO 511 char da terminale. In ogni caso, devi stabilire un limite superiore alla dimensione della stringa.
Scusami, sono di coccio: ho provato a creare qualcosa sul tuo spunto, ma non riesco a sostituire la gets

Non è che me le puoi scrivere te le righe di codice da mettere per risolvere? Grazie!
morpheus · 30/08/2007 00:15 · #6Esempio stupido, la gestione degli errori è un po' cruda, ma penso che renda l'idea
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 512
int
main (int argc, char **argv)
{
/* Al massimo 511 caratteri + NULL finale */
char buffer[BUFSIZE];
char *p = NULL;
printf ("Inserire una stringa: ");
p = fgets (buffer, BUFSIZE, stdin);
if (!p)
{
fprintf(stderr, "Impossibile leggere la stringa (errore o EOF inatteso)\n");
exit (1);
}
/* Rimuove il newline finale o termina forzatamente la stringa */
p = (char *) memchr (buffer, '\n', BUFSIZE);
if (p == NULL)
buffer[BUFSIZE - 1] = '\0';
else
*p = '\0';
printf ("Stringa inserita: %s\n", buffer);
exit (0);
} seneca · 30/08/2007 12:41 · #7Ho corretto il programma in questo modo:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFSIZE 512
char * cancella(char *str, char c)
{
/*rimasta uguale*/
}
main()
{
char x[2];
char *a="s", *b="n";
char *s="sschissa se ss s sfunzionassssss";
printf("La frase da esaminare è: %s\n", s);
printf("Vuoi cambiare la frase? s/n\n");
scanf("%s", x);
if (strcmp(x, b)==0)
printf("%s\n", cancella(s, 's'));
else if (strcmp(x, a)==0)
{
printf("Scrivi la nuova frase:\n");
/* Al massimo 511 caratteri + NULL finale */
char buffer[BUFSIZE];
char *p = NULL;
p = fgets (buffer, BUFSIZE, stdin);
if (!p)
{
fprintf(stderr, "Impossibile leggere la stringa (errore o EOF inatteso)\n");
exit (1);
}
/* Rimuove il newline finale o termina forzatamente la stringa */
p = (char *) memchr (buffer, '\n', BUFSIZE);
if (p == NULL)
buffer[BUFSIZE - 1] = '\0';
else
*p = '\0';
printf("%s\n", cancella(buffer, 's'));
}
else
printf("Opzione non valida\n");
}Ho provato il tuo codice come me l'hai postato, ho provato anche la gets in un mini programma dove prende una frase in input da tastiera ed entrambi funzionano! Poi li vado ad inserire nel contesto e c'è sempre il solito malfunzionamento: se scelgo di cambiare la frase mi autoimmette una riga bianca dopo "Scrivi la nuova frase" e termina il programma riportandomi al normale prompt. Se invece metto una scanf e naturalmente scrivo una sola parola funziona tutto normalmente, ci sto diventando matto! Tu hai idea della soluzione?
Grazie comunque per l'aiuto.
Ciao!
morpheus · 31/08/2007 13:40 · #8*CREDO* dipenda dall'uso "misto" di scanf e fgets, ma non ho controllato più di tanto.
Prova a sostituire la scanf
