1. Sistemi operativi
/*Esame di sistemi operativi:scrivere una shell semplificata(comandi dir-type-
copy-move) a menù.Complessità 0.3.
a cura di Fabiano Dalla Piazza cdl in ingegneria informatica
Il programma è composto da un programma principale MAIN e quattro sottoprogrammi:
COPIA,SPOSTA,DIRET e VISUALIZZA.Il Main chiede quale comando eseguire,su quale
file eseguirlo e memorizza queste richieste.In base al comando digitato chiama
il relativo sottoprogramma.Il sottoprogramma Copia(Copy) riceve in ingresso i file
di ingresso e destinazione e li apre rispettivamente in lettura e scrittura
associandogli un flusso di dati rispettivamente in ingresso e uscita.Poi copia
un carattere alla volta e quando non ci sono più caratteri azzera e chiude
l'oggetto associato in lettura e chiude quello in scrittura.Il comando Sposta(Move)
è una combinazione dei comandi copia e dopo elimina il file di origine.Così ripete
inizialmente la stessa procedura del comando Copia,inserendo però dei controlli
sull'avvenuta procedura di copiatura.Se questa è accaduta, elimina il file di
partenza,altrimenti termina con un nulla di fatto.Il comando Visualizza(Type)
riceve in ingresso il nome del file da visualizzare,crea uno stream di dati
in ingresso collegato al file,copia i caratteri su schermo,infine azzera l'oggetto
associato e lo chiude.Il comando Diret(Dir dell' Ms Dos o Ls Unix) riceve il nome
della directory da aprire in ingresso,vi accede,verifica che il file sia una
directory e se lo è,apre il file in lettura(in UNIX una directory è sempre un file).
Legge i file contenuti nella directory,descrive le sue caratteristiche e chiude la
directory.
direttive al preprocessore per le librerie*/
#include <iostream.h>
#include <conio.h>
#include <fcntl.h>
#include <stdio.h>
#include <fstream.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
#include <string.h>
/*prototipi di funzioni*/
void copia(char s3[],char s4[]);
void sposta(char s3[],char s4[]);
void diret(char *nome);
void visualizza(char s[]);
/*programma principale*/
void main(){
/*dichiarazione delle variabili*/
char s;
1agina p
2. Sistemi operativi
char s1[16],s2[16],s3[16],s4[16];
char *nome;
/*interfaccia:viene richiesta la digitazione di un tasto*/
cout << "Scegliere il tasto da digitare:n"
<< "c)Comando Copy per copiare un filen"
<< "d)Comando Dir per visualizzare un direttorion"
<< "m)Comando Move per spostare un filen"
<< "t)Comando Type per visualizzare un filen"
<< "u)Per uscire" << endl;
/*cicla se non viene digitato il tasto u,e in base al tasto esegui il comando*/
while((s=getch())!= 'u'){
/*scelta multipla*/
switch(s){
/*se è stato scelto il tasto c,il programma richiede il file da copiare,
lo memorizza,richiede il file su cui copiare,chiama il sottoprogramma
copia ed esce dal ciclo switch*/
case 'c':cout << "Quale file desideri copiare?n";
cin >> s1;
cout << "Il nome del file su cui copiare?n";
cin >> s2;
copia(s1,s2);
break;
/*se è stato scelto il tasto d,il programma chiede il nome della
directory da listare,lo memorizza,chiama il sottoprogramma
diret ed esce dal ciclo switch*/
case 'd':cout << "Digita il nome della directory da listaren";
cin >> nome;
diret(nome);
break;
/*se è stato scelto il tasto m,il programma chiede il nome del
file da spostare,lo memorizza,chiede su quale file spostarlo,
chiama il sottoprogramma sposta ed esce dal ciclo switch*/
case 'm':cout << "Quale file desideri spostare?n";
cin >> s3;
cout << "Su quale file desideri spostarlo?n";
cin >> s4;
sposta(s3,s4);
break;
/*se è stato scelto ilo tasto t,il programma chiede il nome del
file da visualizzare,lo memorizza,chiama il sottoprogramma
visualizza ed esce dal ciclo switch*/
2agina p
3. Sistemi operativi
case 't':cout << "Quale file desideri visualizzare?n";
cin >> s1;
visualizza(s1);
break;
/*se è stato scelto un tasto sconosciuto un messaggio avvisa
dell'errore ed esce dal ciclo switch*/
default:cout << "Comando sconosciuto.Riprovan";
break;
}//switch
}//while
}//main
/*sottoprogramma copia*/
void copia(char s3[],char s4[]){
/*dichiara le variabili intera,carattere e stream(flusso) di dati
in ingresso(leggi) e uscita(scrivi)*/
char c;
int conta;
fstream leggi;
fstream scrivi;
/*open associa all'oggetto leggi(uno stream) l'oggetto s3(il file da
copiare;quindi viene aperto in lettura il file s3 da copiare*/
leggi.open(s3,ios::in);
/*se l'apertura fallisce avverte l'utente*/
if(leggi.fail())cout << "Apertura file in lettura fallita!n";
/*open associa all'oggetto scrivi(uno stream) l'oggetto s4(il file su
cui copiare;quindi viene aperto in scrittura il file su cui copiare*/
scrivi.open(s4,ios::out);
/*se l'apertura fallisce avverte l'utente*/
if(scrivi.fail())cout << "Apertura file in scrittura fallita!n";
/*inizializza la variabile che conta il numero dei caratteri*/
conta=0;
/*cicla finché non raggiunge fine file o fallisce*/
do{
/*legge un carattere alla volta sul file da copiare*/
leggi >> c;
/*condizioni di interruzione ciclo*/
if(leggi.fail()||leggi.eof())break;
3agina p
4. Sistemi operativi
/*eco su schermo*/
cout << c;
/*scrittura sul file di destinazione*/
scrivi << c;
/*Incrementa il contatore*/
conta++;
}while(1);
cout << "nSono stati copiati " << conta << " caratteri"
<< "n====FINE FILE====nAspetto taston";
/*aspetta tasto,azzera lo stato del file da copiare(clear) e chiude lo
stream collegato ai file(close)*/
getch();
leggi.clear();
leggi.close();
scrivi.close();
}//copia
/*sottoprogramma sposta*/
void sposta(char s3[],char s4[]){
/*dichiara le variabili intere e booleana e gli stream verso file*/
char c;
int conta,rimosso;
bool successo=true;
fstream leggi;
fstream scrivi;
/*apre lo stream di dati in ingresso nel file da copiare*/
leggi.open(s3,ios::in);
/*se l'apertura fallisce,avverte l'utente e assegna alla variabile
booleana il valore di copiatura fallita(successo=false)*/
if(leggi.fail()){
cout << "Apertura file in lettura fallita!n";
successo=false;
}//if
/*apre lo stream di dati in uscita nel file di destinazione*/
scrivi.open(s4,ios::out);
/*se l'apertura fallisce,avverte l'utente e assegna alla variabile
booleana il valore di copiatura fallita(successo=false)*/
if(scrivi.fail()){
cout << "Apertura file in scrittura fallita!n";
4agina p
5. Sistemi operativi
successo=false;
}//if
/*inizializza la variabile che conta il numero di caratteri*/
conta=0;
/*cicla finché non sono a file file o fallisce*/
do{
/*legge un carattere alla volta dal file di origine*/
leggi >> c;
/*condizioni di fine ciclo*/
if(leggi.fail()||leggi.eof())break;
/*eco su schermo*/
cout << c;
/*copia sul file di destinazione*/
scrivi << c;
/*incrementa il contatore*/
conta++;
}while(1);
/*se non ha copiato nulla, la copiatura è fallita*/
if(conta == 0)successo=false;
else cout << "nSono stati copiati " << conta << " caratteri";
/*segnala il fine file,aspetta tasto a piacere,azzera lo stream del
file di lettura e chiude entrambi gli stream*/
cout << "n====FINE FILE====nAspetto taston";
getch();
leggi.clear();
leggi.close();
scrivi.close();
/*se la copiatura è avvenuta posso rimuovere il file di partenza
e se la rimozione non è accaduta viene segnalato*/
if(successo == true){
rimosso=remove(s3);
if(rimosso != 0)cout << "Il file originale non è stato rimosson";
}//if
/*se la copiatura non è avvenuta,non cancello il file di partenza
e lo segnala*/
else{
cout << "Il file non è stato copiaton";
}//else
5agina p
6. Sistemi operativi
}//sposta
/*sottoprogramma diret*/
void diret(char *nome){
/*dichiara le variabili intera(conta),puntatore a struttura dell'entry
directory(*z),puntatore a struttura directory(*dirlst),puntatori a
struttura per la definizione del formato tempo*/
struct stat stbuf;
struct tm *timeinfo,*timeinfo1,*timeinfo2;
DIR *dirlst=NULL;
dirent *z=NULL;
int conta;
/*se la chiamata di sistema stat non ha successo,visualizzo il
messaggio ed esco*/
if(stat(nome,&stbuf) == -1){
cout << "nNon riesco ad accedere alla directoryn";
exit(1);
}//if stat -1
/*se è una directory*/
if((stbuf.st_mode & S_IFMT) == S_IFDIR){
/*apre la directory e fallisce,invia un messaggio ed esce*/
if((dirlst = opendir(nome)) == NULL){
cout << "nNon riesco ad aprire la directoryn";
exit(1);
}//if
/*invia un messaggio e azzera il contatore*/
cout << "nla directory " << nome << " contiene:" << endl;
conta=0;
/*cicla la directory in lettura restituendo un puntatore
finché non trova oggetti a cui puntare*/
while((z=readdir(dirlst)) != NULL){
/*se la directory è quella corrente o quella genitore esce
dal ciclo e riprende l'esecuzione dall'inizio,evitando
l'innescarsi di un ciclo infinito*/
if(strcmp(z->d_name,".") == 0 || strcmp(z->d_name,"..") == 0){
continue;
}//if strcmp
/*incrementa il contatore di file e visualizzali*/
++conta;
cout << conta << ") file=" << z->d_name << endl;
6agina p
7. Sistemi operativi
}//while
/*se non ci sono file viene segnalato*/
if(conta == 0) cout << "Non ci sono file nella directoryn";
/*se ci sono scrive le caratteristiche della directory*/
else{
cout << "Numero di file contenuti nella directory=" << conta
<< "nDimensione é di " << stbuf.st_size << " caratteri";
time(&stbuf.st_ctime);
timeinfo = localtime(&stbuf.st_ctime);
cout << "nData di creazione=" << asctime(timeinfo);
time(&stbuf.st_atime);
timeinfo1 = localtime(&stbuf.st_atime);
cout << "Data di ultimo accesso=" << asctime(timeinfo1);
time(&stbuf.st_mtime);
timeinfo2 = localtime(&stbuf.st_mtime);
cout << "Data di ultima modifica=" << asctime(timeinfo2) << endl;
}//else
/*chiude la directory*/
closedir(dirlst);
}//if
/*se non è una directory*/
else{
cout << "Il file richiesto non è una directoryn";
exit(1);
}//else
}//diret
/*sottoprogramma visualizza*/
void visualizza(char s[]){
/*dichiara le variabili intere,carattere e stream di dati*/
fstream f;
int linee,conta;
char c;
/*apre uno stream di dati in ingresso sul file da leggere*/
f.open(s,ios::in);
/*se l'apertura fallisce lo segnala*/
if(f.fail())cout << "Apertura file fallitan";
/*ciclo valido finchè non sono a fine file o non fallisce*/
for(;;){
7agina p
8. Sistemi operativi
/*visualizzo il numero progressivo della linea*/
cout << linee << '.';
/*ciclo di lettura caratteri*/
for(;;){
/*ottengo il carattere da leggere*/
c=f.get();
/*se sono a fine linea,fine file o c'è un errore esco dal
primo ciclo*/
if((c==10)||(f.eof())||(f.fail()))break;
/*incrementa il contatore del numero di caratteri*/
conta++;
/*eco su schermo*/
cout << c;
}//for
/*se sono a fine file file o c'è un errore*/
if(f.eof() || f.fail())break;
/*incrementa il contatore del numero di linee*/
linee++;
/*ogni 60 caratteri va a caporiga*/
if((linee%60)==0) cout << 'n';
}//for
/*toglie l'ultima linea(non completa)*/
linee--;
/*non conta l'ultimo carattere*/
conta--;
/*riepiloga i dati,aspetta un tasto qualunque,azzera lo stream e chiude*/
cout << "Il file " << s << " ha " << conta << " caratteri e " << linee << " lineen";
cout << "Aspetto tasto!n";
getch();
f.clear();
f.close();
}//visualizza
8agina p