Stdin e file di testo contemporaneamente

di il
8 risposte

Stdin e file di testo contemporaneamente

Salve a tutti,
mi affido nuovamente a voi.

Ho un file di testo non vuoto con stringhe che rispettano una determinata struttura:
Parola : abc
simbolo : >
Parola : abc

Inserisco da stdin una stringa di testo che rispetti tale struttura
e fin qui non ho riscontrato problemi.

Però quando volgio andare a stampare,stampa solo quello che ho scritto da stdin,ma non dal file
di testo,
Mi sapreste dire come fare a stampare tutto:da stdin e dal file di testo?

Grazie.

8 Risposte

  • Re: Stdin e file di testo contemporaneamente

    Non hai spiegato cosa fai col file di testo: se lo apri metti ciò che hai letto da stdin ecc.
  • Re: Stdin e file di testo contemporaneamente

    Non vorrei modificare il file ,dal quale voglio solo visualizzare il contenuto.

    In parole povere,con stdin aggiungo elementi alla struttura e poi visualizzo il numero di elementi totali(stdin + file) e poi visualizzarli,come fosse un unica sorgente,ma cercando di non aggiungere nulla al file.
    è complesso lo so,ma lo devo fare e non so da dove iniziare
  • Re: Stdin e file di testo contemporaneamente

    Leggi da file e metti i campi nel vettore di struct. Poi leggi da stdin a aggiungi struct a questo vettore. Alla fine stampa tutto.
  • Re: Stdin e file di testo contemporaneamente

    Scusa se ti stresso,ma non riesco a venirne a capo,se ti dò le strutture,mi dici come fare?


    
    typedef char Symbol;
    
    typedef struct
    {
            Symbol word [MAX_WORD_LENGTH];
            unsigned length;
    } Word;
    
    typedef struct
    {
            Word left;
            Word right;
    } Production;
    
    typedef struct
    {
            Production productions[MAX_PRODUCTIONS];
            unsigned numprod;
    } Grammar;
    



    come creo e riempio un vettore di struct?
    Grazie per l'aiuto.
  • Re: Stdin e file di testo contemporaneamente

    
    Grammar theGrammar;
    
    theGrammar.productions[i].left.word //è la parola a sinistra
    theGrammar.productions[i].left.length =  strlen(theGrammar.productions[i].left.word) //lunghezza parola sinistra
    
    theGrammar.productions[i].right.word //è la parola a destra
    theGrammar.productions[i].right.length =  strlen(theGrammar.productions[i].right.word) //lunghezza parola destra
    
    
    come vedi un Grammar ha già dentro un array di strutture di tipo production quindi l'array c'è già.
    Tu devi giocare con il tuo theGrammar.numprod e devi rispecchiare l'inserimento dei dati.
    un inserimento può essere del tipo:
    
    Symbol leftWord [MAX_WORD_LENGTH];
    Symbol rightWord [MAX_WORD_LENGTH];
    
    fscanf(fp,"%s%*s%s",leftWord,rightWord);
    theGrammar.numprod = 0;
    
    strcpy(theGrammar.productions[theGrammar.numprod].left.word,leftWord);
    theGrammar.productions[theGrammar.numprod].left.length = strlen(leftWord);
    
    strcpy(theGrammar.productions[theGrammar.numprod].right.word,rightWord);
    theGrammar.productions[theGrammar.numprod].right.length = strlen(rightWord);
    
    theGrammar.numprod++;
    
    e così via per il resto dei dati. Da notare che il codice non è provato ma solo un abbozzo.
  • Re: Stdin e file di testo contemporaneamente

    Vediamo se ho capito:
    Grammar theGrammar;
    
    theGrammar.productions[i].left.word //creo la struttura per memorizzare la parola sinistra
    theGrammar.productions[i].left.length =  strlen(theGrammar.productions[i].left.word) //memorizzo la lunghezza della parte sinistra
    theGrammar.productions[i].right.word //come per la sinistra
    theGrammar.productions[i].right.length =  strlen(theGrammar.productions[i].right.word) //come per la sinistra
    Mentre
    
    
    Symbol leftWord [MAX_WORD_LENGTH]; //dichiarazione  parola sinistra è di tipo Symbol
    Symbol rightWord [MAX_WORD_LENGTH];//dichiarazione  parola destra è di tipo Symbol
    
    
    /*Suppongo che qui dovrei inserire il ciclo:
    ad es:
    while(!feof(stdin))
    {
    */
    
    fscanf(fp,"%s%*s%s",leftWord,rightWord); //Stampa nel file la parola sinistra e la parola destra
    theGrammar.numprod = 0; //Inizialmente la grammatica ha zero produzioni.OK
    
    strcpy(theGrammar.productions[theGrammar.numprod].left.word,leftWord);
    theGrammar.productions[theGrammar.numprod].left.length = strlen(leftWord);
    //copio la stringa della parte sinistra nella struttura leftWord
    
    strcpy(theGrammar.productions[theGrammar.numprod].right.word,rightWord);
    theGrammar.productions[theGrammar.numprod].right.length = strlen(rightWord);
    //copio la stringa della parte destra nella struttura rightWord
    
    theGrammar.numprod++;//incremento numero di produzioni
    //Inserisco } per terminare ciclo while.E stampo dal file direttamente?o sennò da dove.
    
    Ho capito bene o no?
    Cmq grazie mille,giuro che arriverò a scrivere in C senza problemi,proprio perchè:
    P.S.
    Disse il bruco alla mela:

    "Tempo ci vuole ma il buco te lo devo fare"

    Grazie.
  • Re: Stdin e file di testo contemporaneamente

    Ecco come ho risolto:

    Questo è il sorgente completo:
    
    
    #include <stdio.h>
    
    #define MAX_WORD_LENGTH 100
    #define MAX_PRODUCTIONS 100
    
    // Definizione dei tipi ------------------------------------------------------*/
    
    typedef char Symbol;
    
    typedef struct
    {
            Symbol word [MAX_WORD_LENGTH];
            unsigned length;
    } Word;
    
    typedef struct
    {
            Word left;
            Word right;
    } Production;
    
    typedef struct
    {
            Production productions[MAX_PRODUCTIONS];
            unsigned numprod;
    } Grammar;
    
    // Procedure di riconoscimento dei simboli -----------------------------------*/
    
    int is_terminal(Symbol s)
    {
        return (islower(s));
        //return (s >= 'a') && (s <= 'z');
    }
    
    int is_nonterminal(Symbol s)
    {
        return (isupper(s));
        //return (s >= 'A') && (s <= 'Z');
    }
    
    int is_prodsym(Symbol s)
    {
        return (s == '>');
    }
    
    int is_prodsep(Symbol s)
    {
        return (s == '\n');
    }
    
    /* Lettura di simboli da file ------------------------------------------------*/
    
    Symbol read_sym(FILE* file)
    {
           Symbol s;
           
           // fscanf(file,"%c",&s); 
           
           //questo ciclo permette di saltare la lettura di spazi tra i simboli
           do 
              s = getc(file);
           while (s==' ');
           
           return s;
    }
    
    Production* add_new_production(Grammar *g)
    {
      Production* p;
      p = &(g->productions[g->numprod++]);
      p->left.length = 0;
      p->right.length = 0;
      
      return p;
    }
                           
    
    void add_symbol(Word *w, Symbol s)
    {
      w->word[w->length++] = s;  
    }
    
    
    // Procedura di acquisizione di una grammatica da un file --------------------*/
                           
    Grammar* load_grammar(FILE* file, Grammar* g)
    {
             enum States {START,LEFT,RIGHT,ERROR};
             /*   START  = Scansione di una nuova produzione [F]
                  LEFT   = Scansione della parte sinistra
                  RIGHT  = Scansione della parte destra [F]
                  ERROR  = Errore di scansione
             */
             enum States current_state = START;  // Stato iniziale
             Symbol s;
             Production* p;
             
             g->numprod = 0; // Inizializza la grammatica
                      
             while (current_state != ERROR && !feof(file)) 
             {
                   s = read_sym(file);
                   if (feof(file)) break;
                   switch(current_state)
                   {
                   case START:
                        if (is_terminal(s) || is_nonterminal(s))
                        {
                           current_state = LEFT;
                           
                           //p = &(g->productions[g->numprod++]);
                           //p->left.length = 0;
                           p = add_new_production(g);
                           add_symbol(&p->left,s);
                           //L'istruzione precedente corrisponde a p->left.word[p->left.length++] = s;
                        }
                        else if (is_prodsep(s))
                        {
                           current_state = START;
                        }
                        else 
                             current_state = ERROR;
                        break;
                   case LEFT:
                        if (is_terminal(s) || is_nonterminal(s))
                        {
                           current_state = LEFT;
                           add_symbol(&p->left,s);
                        }
                        else if (is_prodsym(s))
                        {
                           current_state = RIGHT;
                        }
                        else
                            current_state = ERROR;
                        break;
                   case RIGHT:
                        if (is_terminal(s) || is_nonterminal(s))
                        {
                           current_state = RIGHT;
                           add_symbol(&p->right,s);
                        }
                        else if (is_prodsep(s))
                        {
                           current_state = START;
                        }
                        else 
                             current_state = ERROR;
                        break;
                   }
             }
             
             if (current_state == START || current_state == RIGHT)
                return g;
             else
                 return NULL;
    
    }       
    
    // Procedure di stampa
    
    void print_sym (Symbol s)
    {
         printf("%c ",s);
    }
    
    
    void print_word (Word* w)
    {
         int i;
         
         for (i=0; i<w->length; i++)
             print_sym(w->word[i]);
    }
    
    void print_production (Production* p) 
    {
         print_word(&p->left);
         printf (" --> ");
         print_word(&p->right);
    }
    
    void print_grammar(Grammar* g)
    {
         int i;
         
         if (g == NULL)
            printf ("Errore! Grammatica non valida! \n");
         else
         {
            printf ("Numero di produzioni: %d\n", g->numprod);
            for (i=0; i<g->numprod; i++)
            {
                print_production(&g->productions[i]);
                printf ("\n");
            }
         }
    }
    
    // MAIN ------------------------------------------------------------------------
    
    int main(int argc, char *argv[])
    {
      char* filename = argv[1];
      FILE* gram_file;
      Grammar grammar;
      
      // controlla se è stato inserito il nome del file
      
      if (filename == 0)
      {
         printf("nome file non specificato \n");
         return -1;
      }
      
      // apertura del file contenente la grammatica
      
      gram_file = fopen(filename,"r");
      if (gram_file == NULL)
      {
         printf("nome di file errato\n");
         return -1;
      }
      
      print_grammar(load_grammar(gram_file,&grammar));
      
      fclose(gram_file);
      
      
      system("PAUSE");	
      return 0;
    }
    
    
    
    Ecco come richiamo la funzione e stampo carattere per carattere dal file.
    
    
    printf("\n\nInserisci produzioni (CTRL+Z per terminare):\n\n");
                    load_grammar(stdin,&grammar);          //carica la grammatica nella struttura con stdin
                    print_grammar(&grammar);            //stampa la grammatica da stdin
                    gram_file = fopen(filename,"r");           //apro file di testo
                   
                    s = fgetc(gram_file);                  //s è di tipo symbol
                    
                     while(s !=EOF )                    //Finche non digiti ctrl+Z
                     { 
                      if (s == '>')               //???????????????voglio sostituirlo con '-->'
                      {
                         printf("-->");
                      }
                       putchar (s); //stampa carattere per carattere
                      }  
                  fclose(gram_file);
    
    

    E' meno articolato,solo che non riesco a saltare il carattere '>'.

    Grazie.
  • Re: Stdin e file di testo contemporaneamente

    
    if (s == '>')               //???????????????voglio sostituirlo con '-->'
                      {
                         printf("-->");
                      }
    else                   putchar (s); //stampa carattere per carattere
    
Devi accedere o registrarti per scrivere nel forum
8 risposte