6 - Uso dei Files
versione 12/02/2013
 
ESERCIZIO
 
Scrivere un programma C che visualizzi il contenuto del file di testo “lab1.txt”, convertendo in maiuscole tutte le lettere presenti nel file (i caratteri che non rappresentano delle lettere non dovranno essere modificati).

 
SOLUZIONE:
OSSERVAZIONI:

1) Per approfondimenti relativi alle funzioni sui files utilizzate clicca sulle sintassi qui sotto elencate:

2) Per le prove usa il seguente file (cut & paste) e salvalo con il nome lab1.txt.

Giochi ogni giorno con la luce dell'universo.
Sottile visitatrice, giungi nel fiore e nell'acqua.
Sei piu' di questa bianca testina che stringo
come un grappolo tra le mie mani ogni giorno.

A nessuno rassomigli da che ti amo.
Lasciami stenderti tra le ghirlande gialle.
chi scrive il tuo nome a lettere di fumo tra le stelle del sud?
Ah lascia che ricordi come eri allora, quando ancora non esistevi.

3) Quando si compila un programma C viene generato un file eseguibile (.exe sotto dos). Questo programma può venire eseguito direttamente scrivendo il suo nome sulla linea di comando. Ai programmi eseguibili è possibile passare degli argomenti (si pensi al comando copy (fa parte del sistema operativo!) che richiede il nome di 2 files: quello del file originale da copiare e quello che dovrà contenere la sua copia.
Il fatto che un programma eseguibile possa leggere i parametri in linea ne aumenta la sua versatilità poichè posso utilizzare il programma in diverse situazioni (un po come avviene per le funzioni di un linguaggio di programmazione).

In C, è possibile accedere a queste informazioni modificando la intestazione della funzione main in questo modo:
int main(int argc, char *argv[]) ...
L'effetto di questa sintassi è che all'interno del programma risultano definite una variabile di tipo intero argc, e un array di stringhe argv. La variabile intera contiene il numero di argomenti con cui il programma è stato lanciato più uno, quindi è semplicemente il numero di stringhe che si trovano sulla linea di comando. Il vettore di stringhe contiene le varie stringhe che compongono la linea di comando: in particolare, argv[0] è il nome del programma stesso, mentre argv[1] è il suo primo argomento, argv[2] è il secondo, ecc.
Con DevC++ i parametri possono essere passati utilizzando l'apposito menu


Soluzione utilizzando fgets()
/**************************************************************************
 * Nome: lab1-maiuscole.c                                                 *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Necessaria solo per system("pause");
#define DIM 80 // Dimensione massima di una riga
/*
 * Nome: main
 * Scopo: Converte i caratteri da minuscolo a maiuscolo
 * Input: int argc: il numero di argomenti specificati da linea di comando
 *        char *argv: la linea di comando che contiene il nome del 
 *        file da convertire
 * Output: 0 se il programma termina correttamente
 */
int main(int argc, char *argv[]) 
{
   	FILE *fp = fopen("lab1.txt", "r");
    char str[DIM];
    int i;

	if (fp != NULL) 
    {
        while(feof(fp) == 0) 
        {
           if (fgets(str, DIM, fp) != NULL) 
           {
                // Controlla carattere per carattere
                // Ascii(Maiuscole)= 'a' && str[i] <= 'z') 
                       printf("%c", str[i] - ('a' + 'A'));
                    else 
                        printf("%c", str[i]);
           }
        }
        fclose(fp);
    }    
    else
       printf("\nErrore apertura file!\n");
    system("pause");
    return 0;
}
Soluzione alternativa utilizzando fgetc()
#include <stdio.h>
#include <stdlib.h> // Necessaria solo per system("pause");
int main(int arcc, char *argv[])
{
    FILE *fp;
    char ch;
    fp=fopen(argv[1],"r");
    if (fp!=NULL)
        while ((ch=fgetc(fp))!=EOF)
            printf("%c",(ch<='z' && ch>='a') ? ch - ('a'-'A') : ch );
    else
        printf("File non trovato!");
    system("pause");
    return 0;
}

ESERCIZIO
 
Scrivere un programma C che visualizzi i 10 numeri interi contenuti nel file binario lab2.dat e successivamente sovrascriva il file invertendo l’ordine dei numeri.

 
SOLUZIONE:
OSSERVAZIONI:

1) Per approfondimenti relativi alle funzioni sui files utilizzate clicca sulle sintassi qui sotto elencate:

2) Per creare il file si può usare il seguente programma

#include <stdio.h>
int main()
{
    FILE *fp;
    int v[10]={ 45, 78, 35, 32, 57, 8, 4, 77 , 91, 123 };
    fp=fopen("lab2.bin","w");
    fwrite(v,sizeof(int),10,fp);
    fclose(fp);
    return(0);
}

3) Per invertire on-fly il contenuto dell'array si è utilizzato questo algoritmo:

- si effettua lo swap tra il primo (v[0]) e l'ultimo elemento (v[n-1]) della lista
- si effettua lo swap tra il secondo (v[1]) e il penultimo elemento (v[n-2]) della lista
- si procede verso il centro della lista effettuando lo swap tra il k-esimo elemento (v[k]) e il (n-k-1)-esimo (v[n--k-1])
- termino quando l'elemento a destra supera l'elemento pescato dalla sottosequenza a destra (k>(n-k-1))


/**************************************************************************
 * Nome: lab2-inverti.c                                                   *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // richiesto da system("pause");
#define N 10
/*
 * Nome: main
 * Scopo: Inverte gli interi binari presenti nel file "lab2.dat"
 * Input: -
 * Output: -
 */
int main() 
{
    int buffer[N], i, n, tmp, s, d;
    // Apro in lettura/scrittura il file
    // e leggo N numeri interi salvandoli in buffer
    FILE *fp = fopen("lab2.dat", "r+b");
    n = fread(buffer, sizeof(int), N, fp);
    // Stampo a video il contenuto prima di essere ordinato
    for (i = 0; i < n; printf("%3d ", buffer[i++]) ); 
    // ALGORITMO
    // partendo dagli elementi esterni procedo verso il centro
    // scambiando di posizione i numeri ad ogni iterazione 
    for (s=0,d=n-1; s < d ; s++,d--)
    {
        tmp = buffer[s];
        buffer[s] = buffer[d];
        buffer[d] = tmp;
    }
    /* Oppure
    for (i = 0; i < n / 2; i++) 
    {
        // swap tra l'i-esimo numero e l'(n-i-1)-esimo
        tmp = buffer[i];
        buffer[i] = buffer[n - i - 1];
        buffer[n - i - 1] = tmp;
    }
    */
    // Stampo a video il contenuto dopo essere stato invertito
    for (printf("\n"), i = 0; i < n; printf("%3d ", buffer[i++]) ); 
    // Riporto il puntatore all'inizio del file e scrivo i numeri
    fseek(fp, 0, SEEK_SET);
    fwrite(buffer, sizeof(int), n, fp);
    fclose(fp);
    printf("\n");
    system("pause");
    return 0;  
}

ESERCIZIO
 
Scrivere due funzioni C che, trattando con un nuovo tipo di dati "Prefisso" che aggrega due stringhe di 20 e 10 caratteri rappresentanti rispettivamente il nome ed il prefisso di un paese, svolga il seguente compito:

– Visualizzi i nomi dei paesi contenuti in un dato file binario (contenente 13 prefissi telefonici). [Suggerimento: void stampa_tutto(FILE *fp);]
– Visualizzi il prefisso telefonico contenuto in un dato file binario corrispondente ad un dato nome di paese. [Suggerimento: void stampa_prefisso(FILE *fp, char str[]);]

Scrivere inoltre un programma C che, sfruttando le funzioni precedentemente definite, visualizzi i nomi dei paesi contenuti nel file binario "prefissi.dat", acquisisca da tastiera il nome di un paese ed infine visualizzi il corrispondente prefisso telefonico nel file.

 
SOLUZIONE:
OSSERVAZIONI:

1) Per approfondimenti relativi alle funzioni sui files utilizzate clicca sulle sintassi qui sotto elencate:

2) Per creare il file si può usare il seguente programma

#include <stdio.h>
#define NCharPaese 20
#define NCharPref 10
#define NPrefix 30
typedef struct 
{
    char paese[NCharPaese];
    char prefisso[NCharPref];       
} tPrefisso;
int main()
{
    FILE *fp;
    tPrefisso Dati[]={
                       { "Italia" , "0039" }, { "Austria", "0043" },
                       { "Belgio", "0032" }, { "Spagna", "0034" },
                       { "Olanda", "0031" }, { "Germania", "0049" },
                       { "Inghilterra", "0044" }, { "Svizzera", "0041" },
                       { "Portogallo", "00351" }, { "Norvegia", "0047" },
                       { "Svezia", "0046" }, { "USA", "001" }, { "Russia", "007" }
                     };
    /* Posso anche inizializzare in questo modo:
    tPrefisso Dati[]={ 
                       "Italia",      "0039", 
                       "Austria",     "0043",
                       "Belgio",      "0032",
                       "Spagna",      "0034",
                       "Olanda",      "0031",
                       "Germania",    "0049",
                       "Inghilterra", "0044",
                       "Svizzera",    "0041",
                       "Portogallo",  "00351",
                       "Norvegia",    "0047",
                       "Svezia",      "0046",
                       "USA",         "001",
                       "Russia",      "007"
                     };
    */
    fp=fopen("prefissi.dat","w");
    // scrivo n record che hanno una dimensione: sizeof(tPrefisso) 
    fwrite(Dati,sizeof(tPrefisso),sizeof(Dati)/sizeof(tPrefisso),fp);
    // oppure scrivo una sola volta (1) un numero di byte pari alla dimensione 
    // dell'array di strutture:
    // fwrite(Dati,sizeof(Dati),1,fp);
    fclose(fp);
    return(0);
}

/**************************************************************************
 * Nome: lab3-stampaPrefissi.c                                            *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCharPaese 20
#define NCharPref 10
#define NPrefix 30
typedef struct 
{
    char paese[NCharPaese];
    char prefisso[NCharPref];       
} tPrefisso;
/*
 * Nome: Stampa_IPaesi_NelFile
 * Scopo: Stampa il nome dei paese contenuti in un dato file binario
 * Input: FILE *fp: il file da stampare
 * Output: -
 */
void Stampa_IPaesi_NelFile(FILE *fp) 
{
    tPrefisso p[NPrefix];
    int i, n;
    rewind(fp); // parto dall'inizio
    n = fread(p, sizeof(tPrefisso), NPrefix, fp); // n contiene il nr di record letti
    printf("Stampa dei prefissi internazionali (%d):\n",n);
    for (i = 0; i < n; i++) 
        printf("%-20s -> %-10s\n",p[i].paese, p[i].prefisso); //-10s allinea a sx        
}
/*
 * Nome: Cerca_Stampa_Prefisso
 * Scopo: Stampa il prefisso di un dato paese contenuto in un dato file binario
 * Input: FILE *fp: il file che contiene i prefissi
 *        char str[]: nome del paese
 * Output: -
 */
int Cerca_Stampa_Prefisso(FILE *fp, char str[]) 
{
    tPrefisso p;
    fseek (fp, 0, SEEK_SET); // parto dall'inizio
    while (feof(fp) == 0)    // oppure !feof(fp)
    {
       fread(&p, sizeof(p), 1, fp); //Leggo un singolo record
       if (strcmp(p.paese, str) == 0) 
       {
          printf("Il prefisso di %s e' %s\n",p.paese, p.prefisso);         
          return 0;
       }
    }    
    printf(">> Errore: Paese inesistente!\n");
    return 1;
}
/*
 * Nome:   main
 * Scopo:  Gestione dei prefissi telefonici internazionali
 * Input:  -
 * Output: 0 se il programma termina correttamente
 *         1 se il file che contiene i prefissi non esiste
 */
int main()
{
    char PrefissoCercato[NCharPref];
    int x, r=1;
   	FILE *fp = fopen("prefissi.dat", "rb");
	if (fp != NULL)
    {
        // INPUT
        printf("Digita il paese di cui vuoi sapere il prefisso: ");
        scanf("%s", PrefissoCercato);
        r=Cerca_Stampa_Prefisso(fp, PrefissoCercato);
        Stampa_IPaesi_NelFile(fp);
        fclose(fp);
    }
    else
       printf("\nErrore apertura file!\n");
    system("pause");
    return r;
}

ESERCIZIO
 
Scrivere una funzione C che, trattando con un nuovo tipo di dati "Prefisso" che aggrega due stringhe di 20 e 10 caratteri rappresentanti rispettivamente il nome ed il prefisso di un paese, svolga il seguente compito: – Aggiunga un dato prefisso telefonico ad un dato file binario. [Suggerimento: void aggiungi(FILE *fp, Prefisso p);]

Scrivere inoltre un programma C che, sfruttando le funzioni definite per l’esercizio 3 e la funzione appena definita, acquisisca da tastiera il nome di un paese ed un prefisso telefonico, aggiunga questo dati al file binario "prefissi.dat", acquisisca da tastiera il nome di un paese ed infine visualizzi il corrispondente prefisso telefonico nel file.

 
SOLUZIONE:
OSSERVAZIONI:

1) Per approfondimenti relativi alle funzioni sui files utilizzate clicca sulle sintassi qui sotto elencate:

2) Per creare il file si può usare il seguente programma

#include <stdio.h>
#define NCharPaese 20
#define NCharPref 10
#define NPrefix 30
typedef struct 
{
    char paese[NCharPaese];
    char prefisso[NCharPref];       
} tPrefisso;
int main()
{
    FILE *fp;
    tPrefisso Dati[]={
                       { "Italia" , "0039" }, { "Austria", "0043" },
                       { "Belgio", "0032" }, { "Spagna", "0034" },
                       { "Olanda", "0031" }, { "Germania", "0049" },
                       { "Inghilterra", "0044" }, { "Svizzera", "0041" },
                       { "Portogallo", "00351" }, { "Norvegia", "0047" },
                       { "Svezia", "0046" }, { "USA", "001" }, { "Russia", "007" }
                     };
    /* Posso anche inizializzare in questo modo:
    tPrefisso Dati[]={ 
                       "Italia",      "0039", 
                       "Austria",     "0043",
                       "Belgio",      "0032",
                       "Spagna",      "0034",
                       "Olanda",      "0031",
                       "Germania",    "0049",
                       "Inghilterra", "0044",
                       "Svizzera",    "0041",
                       "Portogallo",  "00351",
                       "Norvegia",    "0047",
                       "Svezia",      "0046",
                       "USA",         "001",
                       "Russia",      "007"
                     };
    */
    fp=fopen("prefissi.dat","w");
    // scrivo n record che hanno una dimensione: sizeof(tPrefisso) 
    fwrite(Dati,sizeof(tPrefisso),sizeof(Dati)/sizeof(tPrefisso),fp);
    // oppure scrivo una sola volta (1) un numero di byte pari alla dimensione 
    // dell'array di strutture:
    // fwrite(Dati,sizeof(Dati),1,fp);
    fclose(fp);
    return(0);
}

/**************************************************************************
 * Nome: lab4-aggiungiPrefisso.c                                          *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCharPaese 20
#define NCharPref 10
#define NPrefix 30
typedef struct 
{
    char paese[NCharPaese];
    char prefisso[NCharPref];       
} tPrefisso;
/*
 * Nome: Stampa_IPaesi_NelFile
 * Scopo: Stampa il nome dei paese contenuti in un dato file binario
 * Input: FILE *fp: il file da stampare
 * Output: -
 */
void Stampa_IPaesi_NelFile(FILE *fp) 
{
    tPrefisso p[NPrefix];
    int i, n;
    rewind(fp); // parto dall'inizio
    n = fread(p, sizeof(tPrefisso), NPrefix, fp); // n contiene il nr di record letti
    printf("Stampa dei prefissi internazionali (%d):\n",n);
    for (i = 0; i < n; i++) 
        printf("%-20s -> %-10s\n",p[i].paese, p[i].prefisso); //-10s allinea a sx        
}
/*
 * Nome: Cerca_Stampa_Prefisso
 * Scopo: Stampa il prefisso di un dato paese contenuto in un dato file binario
 * Input: FILE *fp: il file che contiene i prefissi
 *        char str[]: nome del paese
 * Output: -
 */
int Cerca_Stampa_Prefisso(FILE *fp, char str[]) 
{
    tPrefisso p;
    fseek (fp, 0, SEEK_SET); // parto dall'inizio
    while (feof(fp) == 0)    // oppure !feof(fp)
    {
       fread(&p, sizeof(p), 1, fp); //Leggo un singolo record
       if (strcmp(p.paese, str) == 0) 
       {
          printf("Il prefisso di %s e' %s\n",p.paese, p.prefisso);         
          return 0;
       }
    }    
    printf(">> Errore: Paese inesistente!\n");
    return 1;
}
/*
 * Nome: Aggiungi_NuovoPrefisso
 * Scopo: Aggiungi il prefisso al file dei prefissi
 * Input: FILE *fp: il file che contiene i prefissi
 * Output: -
 */
void Aggiungi_NuovoPrefisso(FILE *fp, tPrefisso p) 
{
     // Mi sposto in fondo al file
     fseek(fp, 0, SEEK_END);
     fwrite(&p, sizeof(p), 1, fp);        
}
/*
 * Nome: main
 * Scopo: Gestione dei prefissi telefonici internazionali
 * Input: -
 * Output: 0 se il programma termina correttamente
 *         1 se il file che contiene i prefissi non esiste
 */
int main() 
{
    char PrefissoCercato[NCharPref];
    tPrefisso p;
    int x, r=1;
    // Lettura e scrittura binaria
   	FILE *fp = fopen("prefissi.dat", "r+b");
	if (fp != NULL)
    {
        // Stampa prima dell'aggiunta
        Stampa_IPaesi_NelFile(fp);
        // RICERCA
        printf("Digita il paese di cui vuoi sapere il prefisso: ");
        scanf("%s", PrefissoCercato);
        r=Cerca_Stampa_Prefisso(fp, PrefissoCercato);
        // AGGIUNTA - Esempio Australia 0061
        printf("Aggiungi Nuovo Prefisso\nInserisci paese: ");
        scanf("%s", p.paese);
        printf("Inserisci prefisso: ");
        scanf("%s", p.prefisso);
        Aggiungi_NuovoPrefisso(fp, p);
        // Stampa dopo l'aggiunta
        Stampa_IPaesi_NelFile(fp);
        fclose(fp);
    }
    else
       printf("\nErrore apertura file!\n");
    system("pause");
    return r;
}

ESERCIZIO
 
Scrivere un programma C che visualizzi (in sequenza) il contenuto di un numero qualsiasi di file di testo, i cui nomi sono definiti dalla riga di comando.

 
SOLUZIONE:
OSSERVAZIONI:

1) I parametri di linea possono essere passati utilizzando l'apposito menu



oppure digitando in una finestra dos il nome del programma seguito dalla lista dei files



2) Per approfondimenti relativi alle funzioni sui files utilizzate clicca sulle sintassi qui sotto elencate:

3) Ricordiamoci che in modo predefinito, ci sono sempre tre "file" aperti:

- lo stdin (la tastiera),
- lo stdout (lo schermo)
- lo stderr (la visualizzazione a schermo dei messaggi d'errore).


4) Per le prove usa i seguenti files (cut & paste) e salvali rispettivamente con i nomi: lab1.txt, lab2.txt e lab3.txt.


Giochi ogni giorno con la luce dell'universo.
Sottile visitatrice, giungi nel fiore e nell'acqua.
Sei piu' di questa bianca testina che stringo
come un grappolo tra le mie mani ogni giorno.

A nessuno rassomigli da che ti amo.
Lasciami stenderti tra le ghirlande gialle.
chi scrive il tuo nome a lettere di fumo tra le stelle del sud?
Ah lascia che ricordi come eri allora, quando ancora non esistevi.

Nel mezzo del cammin di nostra vita
mi ritrovai per una selva oscura,
ché la diritta via era smarrita.

Ahi quanto a dir qual era è cosa dura
esta selva selvaggia e aspra e forte
che nel pensier rinova la paura!

Ei fu. Siccome immobile,
Dato il mortal sospiro,
Stette la spoglia immemore
Orba di tanto spiro,
Così percossa, attonita5
La terra al nunzio sta,

SOLUZIONE 1 - con fgets()

/**************************************************************************
 * Nome: casa1-stampa.c                                                     *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // necessario per system("Pause");
#define nMaxCharRiga 100
/*
 * Nome: main
 * Scopo: Stampa il contenuti di file di testo
 * Input: int argc: il numero di file di testo da stampare
 *        char *argv: la linea di comando che contiene i nomi dei file da stampare
 * Output: se il programma termina correttamente
 */
int main(int argc, char *argv[]) 
{
    int i;
   	FILE *fp;
    char str[nMaxCharRiga];
    // Scorro i files
    for (i = 1; i < argc; i++) 
    { 
      fp = fopen(argv[i], "r");
      if (fp == NULL) 
         fprintf(stderr, "\nErrore apertura file %s!\n", argv[i]);
      else 
      {
            printf("\n---------------------------\n");
            printf("%s\n---------------------------\n",argv[i]);
            while(feof(fp) == 0)
                if (fgets(str, nMaxCharRiga, fp) != NULL) 
                   printf("%s", str);         
            fclose(fp);
      }
    }
    system("pause");
    return 0;
}
SOLUZIONE 2 - con fgetc()

#include <stdio.h>
#include <stdlib.h> // necessario per system("Pause");
#define Linea "---------------------------"
void MostraFile(char p[]) // oppure *p
{
     int ch;
     FILE *fp=fopen(p,"r");
     if (fp!=NULL)
     {
         printf("\n%s\n%s\n%s\n",Linea,p,Linea);
         while ( (ch=fgetc(fp))!=EOF)
               printf("%c",ch);
         fclose(fp);
     }
     else
         printf("File: %s non trovato!\n",p);
}
int main(int argc, char *argv[])
{
    int i;
    if (argc>1)
        for (i=1 ; i < argc ; MostraFile(argv[i++]));
    else
        printf("Utilizzo:\n   Mostra file1 file2 ... fileN\n");
    system("pause");
    return 0;
}

ESERCIZIO
 
Scrivere un programma C che, dato il nome di un file testuale ed una parola specificati tramite la linea di comando, stampi a video le righe del file in cui compare tale parola.

 
SOLUZIONE:
OSSERVAZIONI:

1) Per le prove usa il seguente file (cut & paste) e salvalo con il nome lab1.txt.

Giochi ogni giorno con la luce dell'universo.
Sottile visitatrice, giungi nel fiore e nell'acqua.
Sei piu' di questa bianca testina che stringo
come un grappolo tra le mie mani ogni giorno.

A nessuno rassomigli da che ti amo.
Quindi lasciami stenderti sulla ghirlanda gialla
chi scrive il tuo nome a lettere di fumo tra le stelle del sud?
Ah lascia che ricordi come eri allora, quando ancora non esistevi.
2) Per approfondimenti relativi alle funzioni sui files utilizzate clicca sulle sintassi qui sotto elencate:

3) Per approfondimenti relativi alle funzioni sulle stringhe:

4) Per localizzare la parola all'interno della stringa è stato usato questo metodo:


/**************************************************************************
 * Nome: casa2-grep.c                                                     *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>  // serve per system("pause");
#include <string.h>
#define nMaxCharRiga 100
/*
 * Nome: main
 * Scopo: Stampa le righe che contengono una determinata parola
 * Input: int argc: il numero di file di testo da stampare
 *        char *argv: la linea di comando che contiene il nome del
 *        file da stampare e la parola cercata
 * Output: --
 */
int main(int argc, char *argv[]) 
{
    char Linea[nMaxCharRiga];
    int i, j, n;
    if (argc>1)
    {
    	FILE *fp = fopen(argv[2], "r");
        if (fp != NULL) 
        {
            while(!feof(fp)) 
                if (fgets(Linea, nMaxCharRiga, fp) != NULL)   // Legge una riga
                {
                    n=0;
                    if (strlen(argv[1]) <= strlen(Linea) )
                    {
                        for (i = 0; i < (strlen(Linea)-strlen(argv[1]) ) ; i++)
                        { 
                            for (j = 0; j < strlen(argv[1]); j++)
                                if (Linea[i + j] != argv[1][j]) 
                                   break;
                            if (j == strlen(argv[1]))
                               n++;
                        }
                    }
                    if (n>0)
                       printf("(%d) - %s",n, Linea);
                    else
                       printf("      %s", Linea);
                    // In alternativa potevo usare strstr
                    // if (strstr(Linea,argv[1]))
                    //     printf("%s", Linea);
                }
            fclose(fp);
        }
        else
            fprintf(stderr, "\nErrore apertura file!\n");
    }
    else
        printf("Utilizzo:\n   Cerca parola file\n");
    system("pause");
    return 0;
}

ESERCIZIO
 
Scrivere un programma C che, dato il nome di un file di testo definito dalla linea di comando, visualizzi il numero di caratteri, il numero di parole (una parola è una qualsiasi sequenza di caratteri delimitata da uno spazio bianco o un carattere di file linea) ed il numero di righe contenute nel file.

 
SOLUZIONE:
OSSERVAZIONI:

1) Per le prove usa il seguente file (cut & paste) e salvalo con il nome lab1.txt.

Giochi ogni giorno con la luce dell'universo.
Sottile visitatrice, giungi nel fiore e nell'acqua.
Sei piu' di questa bianca testina che stringo
come un grappolo tra le mie mani    ogni giorno.

A nessuno rassomigli da che ti amo.
Lasciami stenderti tra le ghirlande gialle.
chi scrive il tuo nome a lettere di fumo tra le stelle del sud?
Ah lascia che ricordi come eri allora, quando ancora non esistevi.
2) Per approfondimenti relativi alle funzioni sui files utilizzate clicca sulle sintassi qui sotto elencate:

/**************************************************************************
 * Nome: casa3-conta.c                                                    *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // necessario per la funzione system("")
#include <string.h>
#define MAXCHARLINEA 100
/*
 * Nome: main
 * Scopo: Conta caratteri, parole e linee
 * Input: int argc: il numero di argomenti specificati da linea di comando
 *        char *argv: la linea di comando che contiene il nome del file da esaminare
 * Output: -
 */
int main(int argc, char *argv[]) 
{
   	FILE *fp = fopen(argv[1], "r");
    int nrRighe=0, nrParole=0,nrCaratteri=0, i;
    char Linea[MAXCHARLINEA];
	if (fp == NULL)
	{
       printf("\nErrore apertura file!\n");
       exit(0);
    }
    while(feof(fp) == 0) // oppure !feof(fp)
    {
       // fgets carica nella stringa anche \n ed aggiunge in fondo \0
       if (fgets(Linea, MAXCHARLINEA, fp) != NULL) 
       {
          nrRighe++;
          nrCaratteri+= strlen(Linea);
          for (i = 0; (i < MAXCHARLINEA) && (Linea[i] != '\0'); i++) 
          {
              // Se il char corrente non è un separatore e il successivo si ...
              // significa che e' terminata una parola
              if (Linea[i] != ' ' && Linea[i] != '\n' && Linea[i + 1] == ' ' || Linea[i + 1] == '\n')
                 nrParole++;
          }
       }
    }    
    fclose(fp);

    // OUTPUT:
    printf("Nr Caratteri: %d\n",nrCaratteri);
    printf("Nr Righe: %d\n",nrRighe);
    printf("Nr Parole: %d\n",nrParole);

    system("pause");
    return 0;
}

ESERCIZIO
 
Scrivere una funzione C che, trattando con un nuovo tipo di dati "Prefisso" che aggrega due stringhe di 20 e 10 caratteri rappresentanti rispettivamente il nome ed il prefisso di un paese, svolga il seguente compito: – Scriva i prefissi telefonici contenuti in un dato file binario in un secondo dato file testuale. [Suggerimento: void esporta(FILE *fp, FILE *fp_dest);] Scrivere quindi un programma C che, sfruttando la funzione precedentemente definita, copi il contenuto del file binario "Prefissi.dat" in un file testuale il cui nome è specificato dalla linea di comando.

 
SOLUZIONE:
OSSERVAZIONI:

1) Per creare il file si può usare il seguente programma

#include <stdio.h>
#define NCharPaese 20
#define NCharPref 10
#define NPrefix 30
typedef struct 
{
    char paese[NCharPaese];
    char prefisso[NCharPref];       
} tPrefisso;
int main()
{
    FILE *fp;
    tPrefisso Dati[]={
                       { "Italia" , "0039" }, { "Austria", "0043" },
                       { "Belgio", "0032" }, { "Spagna", "0034" },
                       { "Olanda", "0031" }, { "Germania", "0049" },
                       { "Inghilterra", "0044" }, { "Svizzera", "0041" },
                       { "Portogallo", "00351" }, { "Norvegia", "0047" },
                       { "Svezia", "0046" }, { "USA", "001" }, { "Russia", "007" }
                     };
    /* Posso anche inizializzare in questo modo:
    tPrefisso Dati[]={ 
                       "Italia",      "0039", 
                       "Austria",     "0043",
                       "Belgio",      "0032",
                       "Spagna",      "0034",
                       "Olanda",      "0031",
                       "Germania",    "0049",
                       "Inghilterra", "0044",
                       "Svizzera",    "0041",
                       "Portogallo",  "00351",
                       "Norvegia",    "0047",
                       "Svezia",      "0046",
                       "USA",         "001",
                       "Russia",      "007"
                     };
    */
    fp=fopen("prefissi.dat","w");
    // scrivo n record che hanno una dimensione: sizeof(tPrefisso) 
    fwrite(Dati,sizeof(tPrefisso),sizeof(Dati)/sizeof(tPrefisso),fp);
    // oppure scrivo una sola volta (1) un numero di byte pari alla dimensione 
    // dell'array di strutture:
    // fwrite(Dati,sizeof(Dati),1,fp);
    fclose(fp);
    return(0);
}

2) Per approfondimenti relativi alle funzioni sui files utilizzate clicca sulle sintassi qui sotto elencate:

/**************************************************************************
 * Nome: lab4-aggiungiPrefissi.c                                          *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define NCharPaese 20
#define NCharPref 10
#define NPrefix 30
typedef struct 
{
    char paese[NCharPaese];
    char prefisso[NCharPref];       
} tPrefisso;
/*
 * Nome: Esporta
 * Scopo: Esporta i prefissi in un file
 * Input: FILE *fp: il file da esportare
 * Output: -
 */
void Esporta(FILE *fp, FILE *fp_dest)
{
	tPrefisso p;
	fseek (fp, 0, SEEK_SET);
	while(feof(fp) == 0) // !feof(fp)
	{
	   if (fread(&p, sizeof(p), 1, fp) > 0)
		  fprintf(fp_dest, "%12s\t%10s\n", p.paese, p.prefisso);         
	}
}
/*
 * Nome: main
 * Scopo: Gestione dei prefissi telefonici internazionali
 * Input: -
 * Output: 0 se il programma termina correttamente
 *         1 se il file che contiene i prefissi non esiste
 */
int main(int argc, char *argv[]) 
{
	FILE *orig, *dest;
	orig = fopen("prefissi.dat", "rb");
	dest = fopen(argv[1], "w");
	if (orig == NULL || dest == NULL) 
    {
       printf("\nErrore apertura file!\n");
       exit(0);
    }

    Esporta(orig, dest);
    fclose(orig);
    fclose(dest);
    return 0;
}

ESERCIZIO
 
Testo esercizio
 
SOLUZIONE:
Soluzione C++
Soluzione JavaScript
Soluzione VBA
Soluzione ASP
Soluzione PHP