FILE in Struct-C - Alessandro Barazzuol

FILE in Struct-C

//
//  main.c
//  Temp
//
//  Created by Alessandro Barazzuol on 31/01/19.
//  Copyright © 2019 Alessandro Barazzuol. All rights reserved.
//

/*concetti fondamentali:
 
 stringa vuota è "" cioe una stringa "      " == ""
 stringa nulla è quella che contiene NULL cioè 0 cioè puntatore a NULL
 La stringa vuota è quella stringa che non contiene nessun carattere.  Ha la proprietà che aggiunta (concatenata, giustapposta) ad una qualsiasi stringa non ne modifica il valore. Ha proprietà simili allo 0 per l'addizione nei numeri. In C la stringa vuota viene denotata con "" (due doppi apici) e rappresenta il puntatore ad una zona di memoria che contiene il byte con valore '\0'. Viceversa, la stringa nulla è rappresentata dal puntatore NULL.
 Attenzione: la stringa vuota e la stringa nulla sono diverse.
 
 
 
 char amessage[] = "Hello world";
 char *pmessage = "Hello world";
 amessage è un vettore sufficientemente grande da contenere la sequenza di caratteri e lo '\0' che lo inizializzano. I caratteri all'interno del vettore possono cambiare, ma amessage si riferisce alla stessa area di memoria.
 
 pmessage è un puntatore inizializzato in modo che punti ad una stringa costante. Può essere modificato in modo che punti altrove ma non si può modificare il contenuto della stringa.
 
 Confrontate il comportamento dei due frammenti seguenti.
 
 
 Per il C la variabile array a considerata come stringa contiene la stringa "stringhe" e i caratteri a e b finali non vengono considerati perché si trovano dopo lo \0. Il C offre un modo sintetico per denotare una stringa che è quello di racchiudere i caratteri che la compongono tra doppi apici.
 Esempio:
 char a[] = "stringhe";
 che equivale a:
 char a[] = {'s','t','r','i','n','g','h','e','\0'};
 Si noti che '\0' viene aggiunto automaticamente usando la notazione con i doppi apici.
 Attenzione: 'A'!="A" perché 'A' denota il codice ASCII del carattere A che è 65, mentre "A" denota il puntatore ad una zona di memoria valida che contiene due byte con i valori 'A' e '\0'. Quindi nel confronto vengono esaminati il carattere 65 a sinistra e il puntatore a questa zona di memoria a destra.
 La maniera corretta per testare è: 'A'==*"A";
 Una stringa va sempre terminata con uno zero finale che denota la fine della stringa.
 Esempio:
 char a[]="a"; //ok lo zero finale viene aggiunto automaticamente;
 char b[1]={'a'} //attenzione non possiamo usare questo array come stringa;
 printf("%s",a); // ok
 printf("%s",b); // ERRORE A RUN TIME
 Questo perché quando una stringa è passata come argomento a delle funzioni sappiamo che passando un puntatore o un array la dimensione della memoria puntata non è ricostruibile. Quindi per determinare la fine di una stringa la convenzione adottata dal C è quella di aspettarsi il byte a zero. Questa convenzione permette di passare solo il puntatore alla zona di memoria senza bisogno di specificare anche la dimensione. In teoria si può usare questa convenzione anche con gli altri tipi di array se è presente un valore per quel tipo che sicuramente non è utilizzato dal programma. Ad esempio,  per un array di puntatori si potrebbe usare il valore NULL per denotare la fine dell'array. Questo implica:
 
 uno spazio aggiuntivo nell'array per memorizzare l'indicatore di fine array;
 il valore usato come indicatore di fine array non può essere memorizzato nell'array.
 Quindi:
 char a[5+1] = "12345"; // serve lo spazio per lo 0 finale!
 a[2] = '\0'; // la stringa diventa "12"; i caratteri 45 sono invisibili come stringa;
 printf("%s", a); // stampa 12;
 a[3] == '4'; //i caratteri 4 e 5 sono ancora memorizzati!
 a[4] == '5';
 
 
 
 */


#include <stdio.h>
#include <stdlib.h>
#include<string.h>


int main()
{
    char ch;
    char *ptc=&ch;
    /*parole di 10 caratteri max*/
    char parola[10]={0};
    /*vettore di stringhe righe di 20 parole di 10
     lettere ognuna*/
    char righe[20][10]={{0},{0}};
    /*matrice di stringhe ..testo di 100 righe */
    char testo[100][20][10]={{0},{0},{0}};
    
    int ncaratteri, nrighe, nparole,nparole_per_riga;
    unsigned char in_parola;
    
    char nomefile[32];
    FILE *fp;
    
    
    
    if ((fp = fopen ("prova.txt", "r")) == NULL)
    {
        printf ("errore di apertura del file %s\n", nomefile);
        exit (EXIT_FAILURE);
    }
    
    
    /* inizializza i contatori */
    ncaratteri = 0;
    nrighe = 0;
    nparole = 0;
    nparole_per_riga=0;
   
    
    while ((ch = fgetc(fp)) != EOF)
    {
        
       if(ch!='\n' && ch!=' ')
       {
           /* analizza il carattere e conta */
           ncaratteri++;
           /*concateno le lettere*/
           strcat(parola,ptc);
          
       }
       else if (ch == '\n')
        {
            nparole_per_riga=nparole-nparole_per_riga;            /*aggiorno l'array riga con la parola*/
            strcpy(righe[nparole],parola);
           
            /*aggiorno l'array testo con la riga*/
    memcpy(testo[nrighe],righe,(nparole_per_riga+1)*ncaratteri);
            
            /*azzera riga*/
            for(int i=0;i<20;i++)
                for(int j=0;j<10;j++)
                    righe[i][j]=0;
            
            
            /*azzera parola*/
             
            for(int i=0;i<10;i++)
                parola[i]=0;
            
            nrighe++;
            nparole++;
         
            
        }
        else if(ch ==' ' && ch!='\n')
        {
            /*aggiorno l'array riga con la parola*/
    
            strcpy(righe[nparole],parola);
            /*azzera parola*/
            
            for(int i=0;i<10;i++)
                parola[i]=0;
            
            nparole++;
            
        }
        
    

    }
 
    strcpy(righe[nparole],parola);
     nparole++;    /*aggiorno l'array testo con la riga*/
   
    memcpy(testo[nrighe],righe,(nparole_per_riga)*ncaratteri);
     nrighe++;
    
    /* stampa il testo */
    int i,j;
    for(i=0;i<nrighe;i++)
    {
        for(j=0;j<nparole;j++)
    {
        if(strcmp(testo[i][j],"")!=0)
        printf("%s ",testo[i][j]);
        
        
    }
         if(strcmp(testo[i][j]," ")!=0)        printf("\n");
    }
    
    
    /* stampa i risultati */
    
    
    
    printf ("caratteri: %d; righe: %d; parole: %d\n",
            ncaratteri, nrighe, nparole);
    
    fclose (fp);
    
    return EXIT_SUCCESS;
}