Prova Pratica 2014.02.20
Revision as of 16:10, 6 May 2017 by FedericoB (talk | contribs) (FedericoB moved page Prova Pratica 20-02-2014 to Prova Pratica 2014.02.20: Uniformazione dei titoli delle pagine di prove pratiche)
Es. 1
Scrivere un programma in C “colonnan” che prenda come parametro il pathname di un file
e un numero intero (che chiameremo n). Il programma deve stampare come output il numero di caratteri presenti
nella n-ma colonna del file se il file e' un file regolare di testo, non deve stampare nulla negli altri casi.
Un file viene considerato di testo se tutti i suoi byte hanno valori compresi nel range 1-127. Per controllare se il
file e' “regolare” usare la system call lstat.
Soluzione di Dado
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char * argv[]){
if(argc!=3){
printf("colonnan: 1st parameter is the pathname, the 2nd is the integer n\n");
}else{
struct stat info;
int ch,i=0,ret=0;
FILE *f;
int res=lstat(argv[1],&info);
int n=atoi(argv[2]);
if(n<=0){
fprintf(stderr, "Error: insert a number >0\n");
exit(-1);
}
if(res){
fprintf(stderr, "Error: lstat\n");
exit(-1);
}
if(S_ISREG(info.st_mode)){
f=fopen(argv[1],"r");
if(!f){
fprintf(stderr, "Error: fopen\n");
exit(-1);
}
while((ch=getc(f))!=EOF){
if(ch >=1 && ch <= 127){
if(ch==(char)'\n')i=0;
else{
i++;
if(i==n) ret++;
}
}else{
fprintf(stderr, "Error: not a text file\n");
}
}
printf("Result: %d\n",ret);
}else{
fprintf(stderr, "File is not a regular file\n");
exit(-1);
}
}
return 0;
}
Es. 2
Si scriva un programma C chiamato “colonnandir”. Il risultato del programma, stampato su standard output, deve essere un
solo numero intero: la somma del numero di caratteri presenti nelle n-me colonne di tutti i file regolari, di testo, non nascosti (il
primo carattere deve essere diverso da punto) della directory passata come parametro, ovvero della directory corrente se
colonnandir viene lanciato senza specificare parametri.
Soluzione di Dado
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
int count_col(char *path, int n){
int ch,i=0,ret=0;
FILE *f;
f=fopen(path,"r");
if(!f){
fprintf(stderr, "Error: fopen\n");
exit(-1);
}
while((ch=getc(f))!=EOF){
if(ch >=1 && ch <= 127){
if(ch==(char)'\n')i=0;
else{
i++;
if(i==n) ret++;
}
}else{
return 0;
}
}
return ret;
}
int main(int argc, char * argv[]){
if(argc!=3){
printf("colonnan: 1st parameter is the dir-name, the 2nd is the integer n\n");
exit(-1);
}else{
DIR *d;
int tot=0;
struct dirent *file;
int n=atoi(argv[2]);
d=opendir(argv[1]);
if(d==NULL){
fprintf(stderr, "Error: open directory\n");
exit(-1);
}
if(n<=0){
fprintf(stderr, "Error: insert a number >0\n");
exit(-1);
}
chdir(argv[1]);
while((file=readdir(d))!=NULL){
if(file->d_name[0]!='.' && file->d_type==DT_REG){
tot+=count_col(file->d_name,n);
}
}
printf("Result: %d\n",tot);
}
return 0;
}
Es. 3
Il comando che dovrete implementare come script shell o programma python e' linkdir. linkdir prende due directory come
parametri.
linkdir dira dirb
e deve creare in dirb un link fisico (non simbolico) a tutti i file regolari che sono in dira e non in dirb. Se un file regolare e'
presente con lo stesso nome sia in dira sia in dirb, nella directory dirb deve rimanere il file originariamente presente se e' piu'
recente di quello in dira altrimenti un link al file di dira con lo stesso nome.
Soluzione di Dado
if [[ -n $1 ]]; then
if [[ -n $2 ]]; then
files=`ls $1`
for file in $files; do
if [[ -f $1/$file ]]; then
if [[ -e $2/$file ]]; then
if [[ $1/$file -nt $2/$file ]]; then
ln -P -f $1/$file $2/$file
fi
else
ln -P $1/$file $2/$file
fi
fi
done
fi
fi
Soluzione di Claudio Kerov
#!/usr/local/bin/bash
if [[ -d $1 ]]; then
if [[ -d $2 ]]; then
dir1=$1
dir2=$2
fi
fi
ris1=`find $dir1 -type f | sort | cut -d "/" -f 2-`
ris2=`find $dir2 -type f | sort | cut -d "/" -f 2-`
indir1=`comm -2 -3 <(echo "$ris1") <(echo "$ris2")`
common=`comm -1 -2 <(echo "$ris1") <(echo "$ris2")`
for nome in $indir1; do
`ln ${dir1}/${nome} $dir2`
done
for file in $common; do
if [[ "${dir1}${file}" -ot "${dir2}${file}" ]]; then
`ln ${dir1}/${file} $dir2`
fi
done
Soluzione di Maldus
import os
import argparse
def main():
parser = argparse.ArgumentParser(description='linkdir')
parser.add_argument('dira', help='directory aggiornata')
parser.add_argument('dirb', help='directory da aggiornare')
args = parser.parse_args()
entrya = os.listdir(args.dira)
entryb = os.listdir(args.dirb)
for f in entrya:
if os.path.isfile(args.dira+'/'+f) and not f in entryb:
os.link( args.dira+'/'+f , args.dirb+'/'+f )
else:
timea = os.path.getmtime(args.dira+'/'+f)
timeb = os.path.getmtime(args.dirb+'/'+f)
if timea > timeb:
os.link( args.dira+'/'+f , args.dirb+'/'+f )
if __name__ == '__main__':
main()