Newsgroup: it.comp.lang.c
Titolo: aiuto x tesina SO

Salve, avrei bisogno di un aiuto per la tesina di Sistemi Operativi...
Considerate che sono alle primissime armi con l'uso del C, e ho letto quasi
tutti i manuali a mia disposizione.
Non riesco a risolvere i problemi del seguente programma, causati
soprattutto dall'utilizzo di un array di puntatori di strutture.
In particolare le righe in cui ottengo l'errore sono le seguenti:
dimensione = (nome->numero_record) + 1;
struct index * nominativi[dimensione];
nominativi[0] = nome;
L'errore che il compilatore restituisce è il seguente:
Errore del compilatore C2143: errore di sintassi: ";" mancante prima di
"tipo"
Di seguito riporto tutto il codice del programma: grazie a chiunque mi dia
una mano...
SONO DISPERATO!!! :-(
ciao
Pinux
#include <stdio.h>
#include <windows.h>
// input/output
#include <iostream.h>
// taglia massima dei campi della rubrica
#define TAGLIA 50
// struttura per i campi della rubrica
struct record
{
 char nome[TAGLIA];
 char indirizzo[TAGLIA];
 char telefono[TAGLIA];
};
// struttura per i campi dell'indice
struct index
{
 char nome[TAGLIA];
 int numero_record; // serve per rintracciare il record
      // nel file della rubrica
};
// Definizione delle variabili globali
DWORD filepointer;
BOOL ris;
unsigned long br, bw;
// Definizione delle Funzioni
void Ricevi_dati(HANDLE, struct record *);
void Invia_dati(HANDLE, struct record *);
void Ricerca_Dati(HANDLE *, HANDLE *, HANDLE *, struct record *, struct
index *);
void Trova_Posizione(HANDLE *, struct index *);
void Ordina_Indice(HANDLE *, struct index *);
void Gestione_Inserimento_Record(HANDLE, HANDLE, HANDLE, struct record *,
struct index *);
void Verifica_Rubrica(struct index );
// Codice relativo alle Funzioni
/*
 Questa funzione viene richiamata dalla funzione
 Gestione_Inserimento_Record().
 Attraverso questa funzione vengono letti da "slot"
 i dati inviati dal Client e li memorizza nei campi
 della struttura utente (di tipo record).
 In ReadFile l'HANDLE slot proviene dalla creazione
 della mailslot tramite CreateMailslot().
 */
void Ricevi_dati(HANDLE slot, struct record * utente)
{
 ris = ReadFile(slot, utente -> nome, TAGLIA, &br, NULL);
 ris = ReadFile(slot, utente -> indirizzo, TAGLIA, &br, NULL);
 ris = ReadFile(slot, utente -> telefono, TAGLIA, &br, NULL);
}
/*
Questa funzione viene richiamata dalla funzione
Ricerca_Dati().
Il server usa tale funzione per comunicare al Client
il record trovato.
Attraverso questa funzione vengono scritti nella "slot"
i campi della struttura utente (di tipo record).
In WriteFile l'HANDLE slot passato come argomento
corrisponde all'HANDLE restituito dalla funzione CreateFile()
chiamato "slot2".
*/
void Invia_dati(HANDLE slot, struct record * utente)
{
 ris = WriteFile (slot, utente -> nome, lstrlen(utente -> nome)+1, &bw,
NULL);
 ris = WriteFile (slot, utente -> indirizzo, lstrlen(utente -> indirizzo)+1,
&bw, NULL);
 ris = WriteFile (slot, utente -> telefono, lstrlen(utente -> telefono)+1,
&bw, NULL);
}
/*
Questa funzione ricerca l'utente nella rubrica a partire
dal nome fornito dal Client come messaggio nella mailslot.
*/
void Ricerca_Dati(HANDLE * file, HANDLE * indice, HANDLE * slot, struct
record * utente, struct index * persona)
{
 HANDLE slot2;
 char nome[TAGLIA];   // buffer di appoggio
 int condizione_ricerca;
 // il server apre la slot2, creata dal Client, in scrittura.
 slot2 = CreateFile("\\\\.\\mailslot\\mailslot2", GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 if (slot2 == INVALID_HANDLE_VALUE)
  {
  printf("\n\nImpossibile accedere alla Mailslot del Client");
  exit(-1);
  }
 // inizializzazione
 condizione_ricerca = 1;
 // inizializza a 0 le aree di memoria delle
 // strutture utente (record) e persona (index) per la loro dimensione.
 memset(&utente, 0, sizeof(utente));
 memset(&persona, 0, sizeof(persona));
 // imposta il file pointer del file indice all'inizio
 SetFilePointer(indice, 0, NULL, FILE_BEGIN);
 // legge dalla slot i primi TAGLIA bytes e li memorizza nel buffer nome
 ris = ReadFile(slot, nome, TAGLIA, &br, NULL);    // ? cambiare TAGLIA con
50
 while(condizione_ricerca)
 {
  // legge dal file indice un nome di una persona
  ReadFile(indice, &persona, sizeof(persona), &br, NULL);
  // confronta il nome persona appena letto, con quello inviato come
messaggio
  // nella slot dal Client.
  if (strcmp(persona -> nome, nome) == 0)
  {
   // se è stato trovato il nome, consente l'uscita dal ciclo while
   condizione_ricerca = 0;
   // imposta il file pointer del file rubrica alla posizione
   // corrispondente al nome trovato.
   SetFilePointer(file, (persona -> numero_record * sizeof(utente)),
FILE_BEGIN, NULL);
   // legge i dati dell'utente trovato dalla rubrica e li mette
   // nella struttura utente
   ReadFile(file, &utente, sizeof(utente), &br, NULL);
   // invia un messaggio al Client nella slot2 che l'utente è stato
   // trovato.
   ris = WriteFile (slot2, "Utente trovato", lstrlen("Utente trovato")+1,
&bw, NULL);
   // lo slot2 è l'HANDLE che deriva da CreateFile()
   Invia_dati(slot2, utente);
  }
  if (br == 0)
  {
   condizione_ricerca = 0;
   ris = WriteFile (slot2, "Utente non trovato", lstrlen("Utente non
trovato")+1, &bw, NULL);
  }
 }
 CloseHandle(slot2);
}
/*
Questa funzione viene invocata all'apertura del Server
per leggere quanti record sono già presenti all'interno
del file indice.
*/
void Trova_Posizione(HANDLE * indice, struct index * nome)
{
 int temp;
 temp = 0;
 // inizializza a 0 la struttura nome (di tipo index)
 memset(&nome, 0, sizeof(nome));
 // inizializza il file pointer di indice all'inizio
 SetFilePointer(indice, 0, NULL, FILE_BEGIN);
 // legge tutto il file indice
 do
 {
  ReadFile(indice, &nome, sizeof(nome), &br, NULL);
  if (temp < nome -> numero_record)
  {
   temp = nome -> numero_record;
  }
 } while (br>0);
 nome -> numero_record = temp;
}
/*
 Questa funzione viene richiamata dalla funzione
 Gestione_Inserimento_Record().
 Questa funzione ha bisogno di 2 parametri:
 1. HANDLE al file indice
 2. Variabile di tipo index contenente il nominativo
 da inserire.
L'ordinamento dei nominativi avviene nella memoria buffer
"nominativi". La funzione memorizza nella posizione iniziale
(nominativi[0]) il nominativo che bisogna inserire.
Carica in questo buffer tutto il contenuto del file indice.
Avviene l'ordinamento in memoria.
Infine, riscrive il contenuto del buffer nel file indice.
*/
void Ordina_Indice(HANDLE * indice, struct index * nome)
{
 int dimensione;
 struct index temp;
 // se il file è vuoto
 if (nome -> numero_record == 0)
  {
   // scrive direttamente il nominativo sul file
   WriteFile(indice, &nome, sizeof(nome), &bw, NULL);
  }
 if (nome -> numero_record != 0)
  {
   // inizializza la variabile locale dimensione
   // al valore del numero_record + 1 (cioè
   // il nominativo che stia per inserire)
      dimensione = (nome->numero_record) + 1;
   struct index * nominativi[dimensione];
   nominativi[0] = nome;
   SetFilePointer(indice, 0, NULL, FILE_BEGIN);
   for (int i = 1; i < dimensione; i++)
   {
    // legge tutto il file dall'inizio e memorizza ogni nome
    // nella i-esima posizione dell'array "nominativi"
    ReadFile(indice, &nominativi[i], sizeof(nominativi[i]), &br, NULL);
   }
   // Ordinamento dell'array
   for (int j = 0; j < dimensione; j++)
   {
    for (int k = j + 1; k < dimensione; k++)
    {
     // confronta il nome nella j-esima posizione con
     // il nome nella k-esima posizione per vedere chi
     // viene prima in ordine alfabetico.
     if ( strcmp(nominativi[j].nome, nominativi[k].nome) > 0 )
     {
      // scambio
      temp = nominativi[j];
      nominativi[j] = nominativi[k];
      nominativi[k] = temp;
     }
    }
   }
   // Dopo aver ordinato in memoria i nominativi
   // scrive sul file indice l'array ordinato.
   SetFilePointer(indice, 0, NULL, FILE_BEGIN);
   for (int s = 0; s < dimensione; s++)
   {
    WriteFile(indice, &nominativi[s], sizeof(nominativi[s]), &bw, NULL);
   }
  }
 // pre-incrementa il numero_record
 ++nome->numero_record;
}
/*
Questa funzione viene richiamata dal main, e gestisce l'inserimento
dei record nei due file, rubrica e indice.
Questa funzine viene richiamata nel momento in cui il Client
invia il messaggio "Scrivi su file".
L'HANDLE slot consente di ricevere i dati di inserimento dalla mailslot,
e li inserisce nelle strutture utente e nome.
Il puntatore &nome corrisponde a info_inserimento passato dal main:
tale parametro contiene il numero_record pari a 0 se non è presente
nessun nominativo, altrimenti corrisponde al valore incrementato di 1.
*/
void Gestione_Inserimento_Record(HANDLE file, HANDLE indice, HANDLE slot,
struct record * utente,struct index * nome)
{
 int temp;
 temp = nome->numero_record;
 // inizializza i due buffer
 memset(&utente, 0, sizeof(utente));
 memset(&nome, 0, sizeof(nome));
 // Imposta il puntatore alla fine del file rubrica,
 // in modo che il successivo nominativo venga
 // aggiunto in coda al file.
 SetFilePointer(file, 0, NULL, FILE_END);
 // Consente di scrivere i dati dalla slot al buffer utente
 Ricevi_dati(slot, utente);
 // Copia il nome dell'utente nella struttura di tipo indice
 strcpy(nome->nome, utente->nome);
 nome->numero_record = temp;
 // Scrive nel file rubrica la struttura utente (di tipo record)
 WriteFile(file, &utente, sizeof(utente), &bw, NULL);
 // Ordina e scrive nel file indice il nuovo nominativo passato
 Ordina_Indice(indice,nome);
}
/*
Questa funzione viene richiamata dal main quando il Client invia il
messaggio
"Verifica rubrica".
*/
void Verifica_Rubrica(struct index persona)
{
 // Il Server apre in scrittura la mailslot "slot2" creata dal Client,
 // per comunicare al Client stesso se la rubrica è vuota o meno.
 HANDLE slot2;
 slot2 = CreateFile("\\\\.\\mailslot\\mailslot2", GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 if (slot2 == INVALID_HANDLE_VALUE)
 {
  printf("\n\nImpossibile accedere alla Mailslot del Client");
  exit(-1);
 }
 // Se non ci sono nominativi già inseriti,
 // il Server scrive un messaggio sulla mailslot "slot2".
 if (persona.numero_record == 0)
 {
  ris = WriteFile (slot2, "Rubrica vuota", lstrlen("Rubrica vuota")+1, &bw,
NULL);
 }
 else
 {
  ris = WriteFile (slot2, "Rubrica non vuota", lstrlen("Rubrica non
vuota")+1, &bw, NULL);
 }
 CloseHandle(slot2);
}
/*
Il main del Server crea la mailslot "slot" per ricevere i messaggi
da parte del Client.
Il main crea un semaforo binario (Mutex) che serve per poter gestire
l'accesso sequenziale dei vari Client. Il Mutex consente la gestione
della sezione critica di accesso alla mailslot da parte dei Client.
La sezione critica dei Client verrà gestita attraverso le funzioni
WaitForSingleObject e ReleaseMutex.
L'accesso alla sezione critica avverrà in modo mutuamente esclusivo,
nel senso che potrà accedervi solo un Client per volta, fino al rilascio
del mutex.
*/
int main(int argc, char *argv[])
{
 int condizione;
 HANDLE slot, file, indice, mutex;
 struct record utente;
 struct index info_inserimento, info_ricerca;
 char buffer_server[TAGLIA];
 // Codice relativo al processo server
 slot = CreateMailslot("\\\\.\\mailslot\\mailslot",         //Creazione
                 TAGLIA,                              //della
        MAILSLOT_WAIT_FOREVER,               //mailslot
        NULL);
 // Controlla se la mailslot è stata creata correttamente
 if (slot == INVALID_HANDLE_VALUE)
  {
  printf("\nErrore nella chiamata CreateMailslot \n");
  ExitProcess(-1);
  }
 // Creazione del semaforo
 mutex = CreateMutex(NULL, FALSE, "Semaforo");
 // Verifica che il semaforo è stato creato correttamente
 if (mutex == NULL)
  {
  printf("\nCreazione del Mutex fallita");
  exit(-1);
  }
 // Creazione del file principale della rubrica
 // Apre il file: la funzione fallisce se il file non esiste.
 file = CreateFile ("rubrica.txt",
        GENERIC_WRITE | GENERIC_READ,
           FILE_SHARE_READ,
           NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
 // se il file non esiste, ne crea uno nuovo.
 if (file == INVALID_HANDLE_VALUE)
 {
  file = CreateFile ("rubrica.txt",
            GENERIC_WRITE | GENERIC_READ,
         FILE_SHARE_READ,
         NULL,
         CREATE_NEW,
         FILE_ATTRIBUTE_NORMAL,
         NULL);
  if (file == INVALID_HANDLE_VALUE)
  {
   printf("\n\nIl Server non puo' creare la rubrica");
   exit(-1);
  }
 }
 // Creazione del file indice.
 // Apre il file: la funzione fallisce se il file non esiste.
 indice = CreateFile ("indice.txt",
                GENERIC_WRITE | GENERIC_READ,
             FILE_SHARE_READ,
             NULL,
          OPEN_EXISTING,
          FILE_ATTRIBUTE_NORMAL,
          NULL);
 // se il file non esiste, ne crea uno nuovo.
 if (indice == INVALID_HANDLE_VALUE)
 {
  indice = CreateFile ("indice.txt",
              GENERIC_WRITE | GENERIC_READ,
           FILE_SHARE_READ,
           NULL,
           CREATE_NEW,
           FILE_ATTRIBUTE_NORMAL,
           NULL);
  if (indice == INVALID_HANDLE_VALUE)
  {
   printf("\n\nIl Server non puo' creare l'indice");
   exit(-1);
  }
  // Dopo aver creato il file indice,
  // inizializza il numero di record.
  info_inserimento.numero_record = 0;
 }
 else
 {
  // se il file indice esiste,
  // legge quanti record sono già presenti all'interno
  // del file indice.
  Trova_Posizione(&indice,&info_inserimento);
  if (info_inserimento.numero_record != 0)
  {
   ++info_inserimento.numero_record;
  }
 }
 // Imposta il Server sulla lettura del messaggio dalla Mailbox
 condizione = 1;
 // Il server rimane in attesa infinita (busy waiting)
 while(condizione)
 {
  ris = ReadFile(slot,
        buffer_server,
        TAGLIA,
        &br,
        NULL);
  if (!ris)
  {
   printf("\nErrore nella chiamata ReadFile da parte del Server\n");
   ExitProcess(0);
  }
  if (strcmp(buffer_server,"Scrivi su file") == 0)
  {
   Gestione_Inserimento_Record(file, indice, slot, &utente,
&info_inserimento);
  }
  if (strcmp(buffer_server,"Ricerca record") == 0)
  {
   Ricerca_Dati(file, indice, slot, &utente, &info_ricerca);
  }
  if(strcmp(buffer_server,"Verifica rubrica") == 0)
  {
   Verifica_Rubrica(info_inserimento);
  }
 }
}

 memset(&nome, 0, sizeof(nome));
idem.
Btw, l'errore che riporti e` dovuto ad un'errore di sintassi,
probabilmente manca un ; od una parentesi da qualche parte... non
dovrebbe essere diffice trovarlo.
Luca
-- 
Home: 
http://kronoz.cjb.net
Il dottore mi ha detto di smettere di fare cene intime per quattro.
A meno che non ci siamo altre tre persone.


A parte il fatto che i compiti li ho fatti già io scrivendo le righe di
codice,
ma a parte questo secondo te io perchè ho chiesto aiuto sull'errore?
Evidentemente
perchè sono alle prime armi e sto imparando e voglio imparare. Se ci sono
errori
io sono il primo che accetta di imparare... Se uso le specifiche Win32
evidentemente
perchè sono OBBLIGATO ad usare Windows e il C (nn C++) per via del
professore.
In ogni caso... grazie lo stesso...
saluti
Pinux


 In ogni caso... grazie lo stesso...
Lasciando perdere le funzioni di I/O di Windows, inizia a sistemare i
problemi con i puntatori che ti ho indicato.
Luca
PS: 
http://www.xs4all.nl/~hanb/documents/quotingguide.html
-- 
Home: 
http://kronoz.cjb.net
#include <stdio.h> 
int main(void) {printf("\t\t\b\b\b\b\b\b");
printf("\t\t\b\b\b\b\b\b");return 0;}