[Algoritmi] C

marcomezzolla
Buongiorno ragazzi, purtroppo non riesco a risolvere un esercizio su liste in C e avrei bisogno di una mano.. Anche per avere un'idea di come procedere.. Il testo è questo:
Un file di testo (stringhe.txt) contiene un numero indefinito di stringhe (di massimo 30 caratteri) da memorizzare in una lista di stringhe. In questa lista, la stringa contenuta in ognuno dei suoi nodi deve essere rappresentata mediante il tipo char* e poi allocata dinamicamente della dimensione opportuna.
Si implementi in linguaggio C:
 una struttura dati adatta a rispondere alle richieste di cui sopra
 una funzione di inserimento in lista, che permetta di aggiungere le stringhe in maniera ordinata (alfabeticamente) man mano che queste sono lette da file

Risposte
minomic
Ciao,
per la struttura dati io farei una tipica struct con un campo char* per la stringa e un link (puntatore alla struct) per il nodo successivo.
La parte di lettura da file non dovrebbe essere difficile.
La parte di inserimento ordinato... nemmeno! Crei il nuovo "nodo", cioè la struct con la sua stringa e il next = NULL, quindi scorri la lista fino a che non incontri il punto giusto dove inserire il nuovo nodo che hai creato. A questo punto modifichi i due next per fare in modo che il nuovo nodo si inserisca al posto giusto.

Prova a scrivere un po' di codice, così poi vediamo se/dove ci sono problemi.

marcomezzolla
"minomic":
Ciao,
per la struttura dati io farei una tipica struct con un campo char* per la stringa e un link (puntatore alla struct) per il nodo successivo.
La parte di lettura da file non dovrebbe essere difficile.
La parte di inserimento ordinato... nemmeno! Crei il nuovo "nodo", cioè la struct con la sua stringa e il next = NULL, quindi scorri la lista fino a che non incontri il punto giusto dove inserire il nuovo nodo che hai creato. A questo punto modifichi i due next per fare in modo che il nuovo nodo si inserisca al posto giusto.

Prova a scrivere un po' di codice, così poi vediamo se/dove ci sono problemi.


minomic, intanto grazie per l'interessamento.. Ma dovrei leggere singolarmente una stringa dal file e poi creare rispettivamente un nodo, oppure leggere tutto il file? Purtroppo non mi è molto chiaro..

minomic
Devi leggere una stringa alla volta, creare il nodo e inserirlo al posto giusto. Quindi passare alla stringa successiva, creare il nodo, ecc.

marcomezzolla
Ho fatto separatamente le funzioni di crezione nodo e inserimento ordinato... ho problemi nel main purtroppo. Il codice che ho abbozzato è questo , ma non so proprio come procedere..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXS 31
typedef struct node *link;
struct node
{
    char *nome;
    link next;
};
link nuovonodo(char*nome,link next);



link insInorder(link n,FILE*);



int main()
{
    FILE *fp;
    link n;
    char tmp_string[MAXS];
    fp=fopen("stringhe.txt","r");
    if (fp==NULL)
        return -1;
    while(fscanf(fp,"%s",tmp_string)!=EOF)
    {
        n->nome=strdup(tmp_string);
        n=nuovonodo(n->nome,n->next);
    }




    return 0;

}
link nuovonodo(char*nome,link next)
{
    link x=malloc(sizeof *x);
    if (x==NULL)
        return NULL;
    else
    {
        x->nome=nome;
        x->next=next;
    }
    return x;
}

link insInorder(link node,FILE*)
{
    link x,p;
    if(node==NULL||strcmp(node->nome,tmp_string))
        return newNode;
    for(x=node->next,p=h; x!=NULL&& strcmp(node->nome,tmp_string); p=x,x->next);

    p->next=newNode ;
    return h;
}

marcomezzolla
"minomic":
Devi leggere una stringa alla volta, creare il nodo e inserirlo al posto giusto. Quindi passare alla stringa successiva, creare il nodo, ecc.

Non so se ti è possibile darci un'occhiata..

vict85
La funzione strdup è una funzione POSIX e/o del "TR 24731-2" (che potrebbe essere incluso come opzionale nei prossimi standard C). Quindi il tuo codice non è a rigore conforme allo standard C.

Detto questo, hai usato una funzione teoricamente più sicura (strdup) ma al contempo ha usato un fscanf(fp,"%s",tmp_string) che è decisamente poco sicuro.

Le stringhe come sono separate? Da un a capo? Da uno spazio?

marcomezzolla
"vict85":
La funzione strdup è una funzione POSIX e/o del "TR 24731-2" (che potrebbe essere incluso come opzionale nei prossimi standard C). Quindi il tuo codice non è a rigore conforme allo standard C.

Detto questo, hai usato una funzione teoricamente più sicura (strdup) ma al contempo ha usato un fscanf(fp,"%s",tmp_string) che è decisamente poco sicuro.

Le stringhe come sono separate? Da un a capo? Da uno spazio?


Le stringhe sono separate da un a capo

vict85
Allora dovresti usare
fgets(tmp_string, sizeof(tmp_string), fp) != NULL
nella condizione al posto di fscanf. Ricordati però che fgets aggiunge il \n nella stringa, quindi devi tenerne conto nella dimensione di tmp_string e decidere se preferisci tenerlo od eliminarlo.

minomic
"vict85":
Allora dovresti usare
fgets(tmp_string, sizeof(tmp_string), fp) != NULL
nella condizione al posto di fscanf. Ricordati però che fgets aggiunge il \n nella stringa, quindi devi tenerne conto nella dimensione di tmp_string e decidere se preferisci tenerlo od eliminarlo.

E nel caso tu preferisca eliminarlo, consiglio di scrivere una funzione (e.g clean_string) che riceva in ingresso una stringa e "rimuova" il carattere \n sovrascrivendolo con il terminatore \0.

vict85
"minomic":
[quote="vict85"]Allora dovresti usare
fgets(tmp_string, sizeof(tmp_string), fp) != NULL
nella condizione al posto di fscanf. Ricordati però che fgets aggiunge il \n nella stringa, quindi devi tenerne conto nella dimensione di tmp_string e decidere se preferisci tenerlo od eliminarlo.

E nel caso tu preferisca eliminarlo, consiglio di scrivere una funzione (e.g clean_string) che riceva in ingresso una stringa e "rimuova" il carattere \n sovrascrivendolo con il terminatore \0.[/quote]

Non l'ho scritto prima ma la presenza del \n serve anche per determinare o meno se le righe sono realmente delle dimensioni scritte. Insomma se la riga contiene più di 30 caratteri allora il \n non è presente.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.