PDA

Visualizza la versione completa : [C] liste di stringhe??


mirkul
20-12-2012, 22:27
Ciao a tutti!!

vorrei creare un progetto in linguaggio C che sfrutta le liste e mi sono bloccato proprio all'inizio...

allora quello che vorrei fare io e' creare una lista che ogni nodo/elemento sia una serie di caratteri cioe' una stringa.. ma volevo acquisire un carattere alla volta e per ogni carattere immesso, applicarci un controllo!

quindi pensavo di prenderlo con getchar() ma non riesco a combinare le cose :D
e poi volevo crearlo dinamico cioe' che e' l'utente a scegliere quanto grosso deve essere questa stringa! non voglio metterci una lunghezza fissa, mi sembra troppo limitante...

un'altro problema che non riesco a risolvere e' di metterci un controllo che quando mi incontra quel carattere mi va a creare un'altro nodo e quindi parte con un'altra stringa..

non so se mi sono fatto capire..

comunque veniamo al codice dove sono arrivato

pistilloi
20-12-2012, 22:39
Di fare qualsiasi altra cosa, hai implementato una lista neutra?

c0der
20-12-2012, 22:40
Originariamente inviato da mirkul
e poi volevo crearlo dinamico cioe' che e' l'utente a scegliere quanto grosso deve essere questa stringa! non voglio metterci una lunghezza fissa, mi sembra troppo limitante...


Qualche limite nei programmi c'è quasi sempre, la lunghezza di riga del prompt dei comandi, di un indirizzo web, tutto ha un limite. Non ti bastano, diciamo 4096 caratteri per riga?
1) man mano che leggi con getchar riempi questo buffer, allocato sullo stack, di 4096 bytes.
2) quando decidi che la riga è finita. allochi un nodo di una lista in cui ci copi i tuoi caratteri inseriti, un nodo del tipo:


struct riga_st {
char *str; // qui ci copi il tuo buffer con un semplice: str = strdup(buf); dove buf è il tuo buffer da 4096 caratteri
struct riga_st *next;
};

mirkul
22-12-2012, 12:58
ciao scusate se poi non avevo postato il codice, mi ero scordato!!

cmq grazie per le risposte, c0der intendevi scritto cosi'??



//dichiarazione delle librerie
#include <stdio.h>
#include <stdlib.h>

//definizione della struttura blocco
typedef struct riga_st {
char *str;
struct riga_st *succ_p;
}riga_str;



int main(int argc, const char * argv[])
{
int num_blocchi,
dim_blocco;
char carattere;

char* str = malloc(dim_blocco*sizeof(char));


printf("inserisci il numero di blocchi che vuoi inserire: \n");
scanf("%d", num_blocchi);

printf("inserisci la dimensione di ogni blocco: ");
scanf("%d", dim_blocco);

printf("inserisci la formula: ");
carattere = getchar();

if ((carattere = getchar()) == 1) {
// devo creare un nuovo blocco per inserire un'altra formula
}




return 0;
}



con questo codice, riesco a creare tot blocchi e di una determinata grandezza e andarci a scrivere e scrive finche non trova un carattere speciale e poi mi crea un'altro blocco???

ciao e grazie per le risposte!!

c0der
22-12-2012, 13:02
Non ti seguo perché nel primo post hai scritto:
<< allora quello che vorrei fare io e' creare una lista che ogni nodo/elemento sia una serie di caratteri cioe' una stringa.. ma volevo acquisire un carattere alla volta e per ogni carattere immesso, applicarci un controllo! >>
ora invece di questa lista non c'è più traccia.

mirkul
23-12-2012, 18:13
ciao coder si hai ragione! infatti quello che avevo scritto era solo un'inizio, ma rileggendo i tuoi messaggi, mi sono accorto di aver letto male...

cioe' te dici di creare un buffer dove ci faccio prendere una riga di caratteri e poi inserisco il tutto dentro il nodo della lista e poi svuoto il buffer e ricomincio con il prossimo nodo... giusto??

ma come faccio a creare un nodo alla volta??

io invece pensavo di fare in uno di questi due modi:

1) determino una grandezza fissa per ogni nodo e arrivederci... ad esempio 5 caratteri
facendo sempre scrivere all'utente cio' che vuole ma inserisco nel nodo solo i caratteri permessi;

2) chiedo all'utente di quanti elementi deve essere composto la lista e quanti elementi puo' contenere ogni nodo e poi faccio scrivere un carattere alla volta e quando incontra un carattere speciale mi punta al nodo successivo...

allora ricapitoliamo: questa e' la mia struttura


/* definizione del tipo di dato "booleano" */
typedef enum { falso,
vero } bool_t;

/* definizione di un elemento della lista */
typedef struct elem_lista
{
char *simbolo; /* simbolo dell'argomento */
struct elem_lista *succ_p; /* puntatore all'elemento successivo */
struct elem_lista *prec_p; /* puntatore all'elemento precedente */
} elem_lista_t;


questa e' la mia funzione di inserimento:


/* definizione della funzione di inserimento di un elemento della lista */
void inserisci_simbolo (char simbolo, /* input: simbolo dell'argomento */
elem_lista_t **testa_p) /* lavoro: punt. all'ind. della testa della lista */
{
/* dichiarazione delle variabili locali alla funzione */
elem_lista_t *nuovo_p, /* lavoro: puntatore al nuovo elemento da inserire in lista */
*corr_p; /* lavoro: puntatore di supporto all'inserimento */

/* viene allocato spazio in memoria per il nuovo elemento */
nuovo_p = (elem_lista_t *)malloc(sizeof(elem_lista_t));

/* viene assegnato il simbolo argomento al nuovo elemento */
nuovo_p->simbolo = simbolo;

/* se la lista è vuota il nuovo elemento viene inserito in testa alla lista */
if (*testa_p == NULL)
{
nuovo_p->succ_p = NULL;
nuovo_p->prec_p = NULL;
*testa_p = nuovo_p;
}


/* altrimenti il nuovo elemento viene inserito in fondo alla lista */
else
{
for (corr_p = *testa_p;
(corr_p->succ_p != NULL);
corr_p = corr_p->succ_p);

corr_p->succ_p = nuovo_p;
nuovo_p->succ_p = NULL;
nuovo_p->prec_p = corr_p;
}
}


ora dovrei fare una funzione per acquisire le stringhe di ogni nodo della lista... una Acquisisci_lista
e qui veramente non so come fare
so soltanto quali controlli dovrei mettere che se vuoi te li scrivo

e poi una funzione che mi stampa tutta la lista

c0der
23-12-2012, 19:37
Ciao, ti darei due consigli.

Leggendo quello che scrivi sembra quasi che sia la prima volta che usi una lista concatenata, è così?
Se così fosse, e tu non stessi facendo tutto questo proprio per studiare le liste, ti consiglierei di studiare le liste a parte e poi una volta che le conosci bene importarne l'uso nel tuo programma.

C'è poi da dire un'altra cosa, se non sei legato al C da qualche motivo, fare tutto questo in C++ sarebbe infinitamente più semplice e breve, vedi questo esempio che ti faccio:


#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main ()
{
vector<string> righe;
string riga;

cout << "inserisci le righe e interrompi con exit" << endl;
while (getline(cin, riga) && riga != "exit")
righe.push_back(riga);

cout << "righe contiene: " << endl;
for (unsigned int i = 0; i < righe.size(); i++)
cout << righe[i] << endl;

return 0;
}


Ciao.

mirkul
24-12-2012, 12:11
ciao c0der grazie delle risposte, il fatto e' che io le liste le ho studiate... sto riguardando su internet altro materiale.... ecc... solo che non ci sono mai degli esempi pratici che ti facciano capire bene come funzionano!!!

girando su internet, trovi soltanto esempi semplici che utilizzano una lista di numeri!!!

mentre delle liste di caratteri dove pi vengono spiegate per bene non le ho trovate, e poi non c'e' mai un'esempio di codice, che mi lea il mio dubbio!

ovvero definita la struttura e definite le classiche funzioni inserimento, eliminazione... ecc..
come faccio io a prendere un valore che l'utente scrive e buttarlo nella lista tramite la funzione di inserimento??
se e' possibile mi puoi togliere questi dubbi e magari farmi un'esempio pratico??
grazie e scusa il disturbo...

p.s ho guardato pure la sezione di questo sito dove parlano delle liste concatenate.. dove spiega un pezzo e subito dopo mette il codice per far vedere in modo pratico coem agiscono...
ho provato ad implementarlo e non so perche' il compilatore mi da alcuni errori -.-

ciao e grazie!!!

mirkul
01-02-2013, 12:42
Ciao alla fine avendo poco tempo a disposizione e non avendo capito bene le liste, ho deciso di cambiare metodo!

adesso vi posto qui sotto come ho fatto, e vorrei un'aiuto per sistemare meglio tutto il codice e per correggerlo nei punti in cui ho sbagliato o poco chiaro!

se provo a compilarlo mi esce fuori il risultato richiesto ma non so se scritto in questa maniera va bene...

poi ci sono alcune cose che vorrei modificare e vorrei un vostro parere;
ad esempio:
- definire in piu funzioni diverse;
- il problema di array di una lunghezza definita;

comunque ho scritto nei commenti in modo piu definito le cose che vorrei modificare e in che modo!



aspetto un vostro aiuto come sempre ciao e grazie


/********************************/
/* Dichiarazione delle librerie */
/********************************/
#include <stdio.h>
#include <stdlib.h>


/* definizione di un elemento della sottoformula*/
typedef struct elem_lista
{
int quant; /**/
char varq;
int neg;
char pred;
char varp;
} elem_lista_t;


/********************************/
/* Dichiarazione delle funzioni */
/********************************/

void stampa_messaggio_iniziale(void);





// definizione del main

int main(int argc, const char * argv[])
{
/* dichiarazione delle variabili locali alla funzione */
char carattere;
int esito;
char varleg[100];
char varlib[100];
int i = -1,
j = -1;
int quant; /* simbolo dell'argomento */
char varq;
int neg;
char pred;
char varp;


/* qui vorrei metterci un menu' che ripete queste due opzioni finche' non si e' scelta una
delle 2 e anche alla fine del punto 1) : 1) inserimento 2) uscita dal programma*/


/* stampa a video del messaggio iniziale del programma */
stampa_messaggio_iniziale();

/* questi comandi li devo mettere in una funzione a parte che inserisce le lettere e
verifica che siano corrette e finche non e' scritto in modo corretto lo fa riscrivere */

while((carattere = getchar()) != '\n')
{
if (carattere == '*' || carattere == '#')
{
esito = ((islower(carattere = getchar()))? 1: 0);
if (!esito)
printf("Dopo un quantificatore ci dev'essere una variabile...\n");
else
{
varq = carattere;
quant = 1;
}
}

else if (carattere == '^')
{
carattere = getchar();
neg = 1;
}

else if (isupper(carattere))
{
esito = ((islower(carattere = getchar()))? 1: 0);
pred = carattere;
if (!esito)
printf("Dopo un predicato ci dev'essere una variabile...\n");
else
{
varp = carattere;
}
}

else if (carattere >= '1' && carattere <= '4')
{
if (varq == varp)
varleg[++i] = varp;
else
varlib[++j] = varp;
}

if (!esito)
{
printf("E' necessario riscrivere la formula\n");
while(getchar() != '\n');
i = j = -1;
}


}


/* questi comandi qui sotto li devo racchiudere in una funzione*/
varleg[++i] = '\0';
varlib[++j] = '\0';


if (varq == varp)
varleg[++i] = varp;
else
varlib[++j] = varp;


printf("DEBUG: Le variabili legate sono: %s\n", varleg);
printf("DEBUG: i = %d, j = %d\n", i, j);
printf("DEBUG: Le variabili libere sono: %s\n", varlib);

// funzione per la verifica della formula
if (j == 0)
printf("la formula e' chiusa");

else
printf("la formula e' aperta");


return 0;
}






/* definizione della funzione di stampa a video del messaggio iniziale del programma */
void stampa_messaggio_iniziale(void)
{
/* viene stampato a video il messaggio iniziale del programma */
printf("\nInserire la formula di logica dei predicati.\n\n"
"==============================\n"
"# = esiste\n"
"* = per ogni\n"
"0 = operatore NOT (¬)\n"
"1 = operatore AND (^)\n"
"2 = operatore OR (v)\n"
"3 = operatore IMPLICAZIONE (->)\n"
"4 = operatore DOPPIA IMPLICAZIONE (<->)\n"
"==============================\n\n"
"Ogni sottoformula deve contenere un solo simbolo di predicato\n"
"Ogni sottoformula deve contenere un solo simbolo di quantificatore\n"
"Ogni sottoformula deve contenere una sola variabile associata al predicato e una sola variabile al quantificatore\n"
"Il simbolo di predicato dev'essere una lettera maiuscola.\n"
"Le variabili devono essere una lettera minuscola\n\n"

"Esempi di sintassi correttamente acquisibili dal programma:\n\n"

"... ");
}

Loading