Ordinamento stringa
Ciao ragazzi! Avrei bisogno di un aiuto da chi di programmazione se ne intende un po' più di me. Ho cercato questioni simili già aperte nel forum ma non ne ho trovate, quindi chiedo.
Devo "Scrivere un programma che, presa una stringa da tastiera, stampi tutti i suoi caratteri in ordine alfabetico.". Ho pensato ad una soluzione dinamica, non sapendo a priori quanto sarà lunga la stringa.
Questo è quello che ho scritto:
Ora, il problema è che Dev C++ me lo fa compilare, ma Windows non me lo fa eseguire, o meglio stampa il primo printf e poi va in tilt. Ho provato ad eseguirlo con una app piuttosto efficente dal tablet, e anche lì stampa il printf, poi stampa "Segmentation Fault". Dove sta il problema? E il codice è corretto?
Devo "Scrivere un programma che, presa una stringa da tastiera, stampi tutti i suoi caratteri in ordine alfabetico.". Ho pensato ad una soluzione dinamica, non sapendo a priori quanto sarà lunga la stringa.
Questo è quello che ho scritto:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) { int i, j; char s1[1000], *stringa, temp; printf("Inserire la stringa da processare: \t"); gets(s1); stringa=(char *)malloc(strlen(s1)*sizeof(char)); strcpy(stringa, s1); free(s1); printf("\nLa stringa inserita e': \"%s\".", *stringa); for (i=0; stringa[i]!='\0'; i++) for(j=0; stringa[j]!='\0'; j++) if(stringa[i]>stringa[j]) { temp=stringa[i]; stringa[i]=stringa[j]; stringa[j]=temp; } printf("\nLa stringa ordinata alfabeticamente e': \"%s\".", *stringa); }
Ora, il problema è che Dev C++ me lo fa compilare, ma Windows non me lo fa eseguire, o meglio stampa il primo printf e poi va in tilt. Ho provato ad eseguirlo con una app piuttosto efficente dal tablet, e anche lì stampa il printf, poi stampa "Segmentation Fault". Dove sta il problema? E il codice è corretto?
Risposte
Ciao,
ti ho corretto il codice:
Gli errori erano principalmente due:
- se dichiari una stringa come "char *stringa", poi nella printf devi passare "stringa" e non "*stringa"
- c'era un errore di logica nell'algoritmo di ordinamento: "i" parte da 0, ma "j" deve partire da "i+1", cioè dal carattere successivo
PS. Anche se il compilatore non segnala errori, fai comunque attenzione ai warning che dà.
PPS. Lascia stare Dev-C++ che è un progetto obsoleto: passa a un IDE più moderno e affidabile come Code::Blocks.
ti ho corretto il codice:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) { int i, j; char s1[1000], *stringa, temp; printf("Inserire la stringa da processare: \t"); gets(s1); stringa=(char *)malloc((1+strlen(s1))*sizeof(char)); strcpy(stringa, s1); printf("\nLa stringa inserita e': \"%s\".", stringa); for (i=0; stringa[i]!='\0'; i++) for(j=i+1; stringa[j]!='\0'; j++) if(stringa[i]>stringa[j]) { temp=stringa[i]; stringa[i]=stringa[j]; stringa[j]=temp; } printf("\nLa stringa ordinata alfabeticamente e': \"%s\".", stringa); return 0; }
Gli errori erano principalmente due:
- se dichiari una stringa come "char *stringa", poi nella printf devi passare "stringa" e non "*stringa"
- c'era un errore di logica nell'algoritmo di ordinamento: "i" parte da 0, ma "j" deve partire da "i+1", cioè dal carattere successivo
PS. Anche se il compilatore non segnala errori, fai comunque attenzione ai warning che dà.
PPS. Lascia stare Dev-C++ che è un progetto obsoleto: passa a un IDE più moderno e affidabile come Code::Blocks.

Grazie mille minomic!

Ora scarico il software che mi hai consigliato!


Ora scarico il software che mi hai consigliato!

Piccolo dubbio appena sopraggiunto mentre ricopiavo il codice:
Nell'assegnazione con il malloc perchè hai scritto "1+strlen"? La dimensione giusta non è proprio quella data dalla funzione strlen? O per caso la strlen non considera il carattere di terminazione e quindi devo aggiungerlo io?
Nell'assegnazione con il malloc perchè hai scritto "1+strlen"? La dimensione giusta non è proprio quella data dalla funzione strlen? O per caso la strlen non considera il carattere di terminazione e quindi devo aggiungerlo io?
Grazie anche a te vict85, ora ho tutto chiaro (almeno su questo problema
)!

Come hanno già sottolineato i colleghi c'era quell'errore logico nell'algoritmo di ordinamento da te utilizzato che, se non erro, è proprio un bubble sort.
Comunque vorrei far notare come anche se cambi piattaforma su cui eseguire il programma (tablet o altro) non è che il risultato sia diverso o che il programma magicamente funzioni
. L'esecuzione può variare soltanto se utilizzi delle particolari primitive di sistema (ad esempio me ne vengono in mente alcune del C se si lavora sotto Linux).
Talvolta sbagliamo proprio perché non proviamo ad eseguire i programmi con carta e penna ma ne lanciamo subito l'esecuzione sperando che venga subito visualizzato l'output corretto.
Comunque vorrei far notare come anche se cambi piattaforma su cui eseguire il programma (tablet o altro) non è che il risultato sia diverso o che il programma magicamente funzioni

Talvolta sbagliamo proprio perché non proviamo ad eseguire i programmi con carta e penna ma ne lanciamo subito l'esecuzione sperando che venga subito visualizzato l'output corretto.
Il codice aveva comunque dei problemi che non sono stati segnalati.
1) Hai scritto
Un modo più intelligente di fare quello che hai fatto era comunque usare malloc con una dimensione sufficiente e poi eventualmente realloc.
2) Hai usato gets che è una funzione deprecata dallo standard C99 e rimossa interamente dallo standard C11. Usarla in un qualsiasi codice che voglia essere portabile e soprattutto sicuro è un grave errore e andrebbe evitato. Dal C11 è stata definita la funzione opzionale gets_s. Essendo opzionale la sconsiglio. Il modo comunemente usato è usare fgets con stdin. Questo errore è presente anche nel codice di minomic.
1) Hai scritto
free(s1);anche se s1 è definita staticamente. È possibile creare variabili che esistono in blocchi più ridotti ma per capirlo devi capire meglio il concetto di scopo di una variabile; cosa che non hai visto con attenzione dato che definisci tutto all'inizio del main (cosa non più necessaria da ormai più di 15 anni). In particolare il fatto che una variabile statica viene automaticamente cancellata alla fine del blocco in cui è definita è molto utile.
Un modo più intelligente di fare quello che hai fatto era comunque usare malloc con una dimensione sufficiente e poi eventualmente realloc.
2) Hai usato gets che è una funzione deprecata dallo standard C99 e rimossa interamente dallo standard C11. Usarla in un qualsiasi codice che voglia essere portabile e soprattutto sicuro è un grave errore e andrebbe evitato. Dal C11 è stata definita la funzione opzionale gets_s. Essendo opzionale la sconsiglio. Il modo comunemente usato è usare fgets con stdin. Questo errore è presente anche nel codice di minomic.
"vict85":
Il codice aveva comunque dei problemi che non sono stati segnalati.
1) Hai scrittofree(s1);
Hai ragione: l'avevo tolto dal codice quando l'ho corretto ma ho dimenticato di segnalarlo a OP.
"vict85":
2) Hai usato gets che è una funzione deprecata [...] Questo errore è presente anche nel codice di minomic.
Sì, avevo notato la "famosa" gets: facile da usare ma pericolosa perché priva del controllo sulla lunghezza del contenuto. Ho evitato di correggerla perché non volevo dare a OP troppe cose a cui pensare tutte insieme e ho cercato di fare solo i cambiamenti minimi al suo codice in modo che funzionasse.
