/*parametristudente.cpp*/

// Lettura dei dati di uno studente dal
// file studenti.dat in modalità binaria:
// il numero dello studente e il nome del file sono
// passati al programma sulla riga di comando.
// Dopo la compilazione, il programma va invocato con
// il comando
//
// parametristudente 2 studenti.dat
//
// dove il primo parametro (2) indica la posizione dello
// studente da leggere, il secondo parametro è il nome
// del file.

#include <iostream>
#include <fstream>

using namespace std;

// Struttura dati dello studente. In un programma ben fatto,
// la definizione dello struct dovrebbe apparire soltanto
// in un file header, così da essere condivisa da tutti i programmi
// che la utilizzano senza essere riscritta.
struct studente {
char nome [100];
int matricola;
};

int main (int argc, char *argv[])
{
// Verifichiamo che il numero di parametri sia corretto
// (il nome del programma è contato come parametro)
if ( argc != 3 ) {
cout << "Errore nell'invocazione del programma: richiesti tre parametri" << endl;
return 1;
}

// Apriamo subito il file per controllare quanti studenti ci sono dentro
ifstream f (argv[2]);

// Verifichiamo che il nome del file sia corretto
if ( !f ) {
cout << "Impossibile aprire il file " << argv[2] << endl;
return 2;
}

// Posizioniamoci alla fine del file
f.seekg (0, ios::end);

// la lunghezza del file divisa per la dimenzione dello struct
// fornisce il numero di studenti già inseriti
int l = f.tellg() / sizeof(studente);

// Convertiamo il primo parametro in un numero intero
int n = atoi (argv[1]);

// Se il numero eccede il numero di studenti presenti nel file, o è minore di 1,
// segnaliamo errore.
if ( n < 1 || n > l ) {
cout << "Il numero indicato, " << n << ", non corrisponde a nessuno studente.\nInserire un numero da 1 a " << l << endl;
return 3;
}

// Dichiariamo una variabile di tipo studente
studente s;

// Posizioniamo il flusso all'inizio del blocco che ci interessa
f.seekg ((n-1)*sizeof(studente), ios::beg);

// Leggiamo il blocco nella variabile s
f.read ((char*)&s, sizeof(studente));

// A questo punto il file non ci serve più
f.close ();

// Scriviamo a video i dati estratti
cout << "Nome: " << s.nome << "\nMatricola: " << s.matricola << endl;

return 0;
}