Difference between revisions of "Prova Pratica 2014.02.20"

From Sistemi Operativi
Jump to navigation Jump to search
(Created page with "==Es. 1== <source lang="text"> Scrivere un programma in C “colonnan” che prenda come parametro il pathname di un file e un numero intero ...")
 
m (Aggiunte soluzioni di altri studenti)
 
(One intermediate revision by the same user not shown)
Line 57: Line 57:
 
}
 
}
 
</source>
 
</source>
 +
 +
===Soluzione di DBoldrin===
 +
<source lang="c">
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <string.h>
 +
 +
int main(int argc, char* argv[]){
 +
  FILE *fp;
 +
  char* pathname = argv[1];
 +
  int contachar=0;
 +
  int contacolonna=0;
 +
  char carattere[2];
 +
  int n=atoi(argv[argc-1]);
 +
  int c;
 +
 +
  fp = fopen(pathname,"r"); // read mode
 +
 +
  if( fp == NULL )
 +
  {
 +
      perror("Error while opening the file.\n");
 +
      exit(EXIT_FAILURE);
 +
  }
 +
 +
  printf("il numero di elementi nella colonna %d del file %s sono:\n",n,pathname);
 +
 +
  while ((c= getc(fp)) != EOF) {
 +
        if ((carattere[1] = c) == '\n')
 +
contacolonna=0;     
 +
    else
 +
contacolonna++;
 +
if(contacolonna==n){
 +
contachar++;
 +
}
 +
 +
}
 +
printf("%d\n",contachar);
 +
  fclose(fp);
 +
  return 0;
 +
}
 +
</source>
 +
 +
 +
===Soluzione di F.Mastromarino e LorenzoV===
 +
<source lang="c">
 +
#include <stdio.h>
 +
#include <unistd.h>
 +
#include <fcntl.h>
 +
#include <sys/stat.h>
 +
 +
int main(int argc, char *argv[]){
 +
int cont=0; int c; int colonna=atoi(argv[1]); int cont2=0;
 +
char *path="/home/francesco/Scrivania/stampa.txt";
 +
int fd=open(path, O_RDONLY, 0664); //0664 sono i permessi per la sola lettura
 +
fd=dup2(fd, STDIN_FILENO); //file stampa.txt come standard input
 +
struct stat buf;
 +
if(lstat(path, &buf)<0 && (buf.st_mode & S_IFMT)!=S_IFREG) // il campo st_mode indica il tipo di file e la costante S_IFREG
 +
//contiene il valore di un file regolare(0100000), S_IFMT è la maschera di bit usata per controllare il tipo di file
 +
return(-1);
 +
do{
 +
cont=0;
 +
do{
 +
 +
c=getchar(); // legge un carattere da file e lo ritorna come un intero
 +
if(c!= EOF && (c>127 || c<1)){ // controllo se è un file ASCII
 +
printf("Non regolare\n");
 +
return(-1);
 +
}
 +
cont++;
 +
if(cont==colonna) cont2++;
 +
}while(c!='\n' && c!=EOF);
 +
}while(c!=EOF); // EOF è l'ultimo carattere del file da leggere
 +
printf("%d\n", cont2);
 +
close(fd);
 +
return(0);
 +
}
 +
</source>
 +
--[[User:F.Mastromarino|F.Mastromarino]] ([[User talk:F.Mastromarino|talk]]) 11:14, 17 March 2015 (CET)
 
==Es. 2==
 
==Es. 2==
 
<source lang="text">
 
<source lang="text">

Latest revision as of 08:37, 10 May 2017

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;
}

Soluzione di DBoldrin

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char* argv[]){
   FILE *fp;
   char* pathname = argv[1];
   int contachar=0;
   int contacolonna=0;
   char carattere[2];
   int n=atoi(argv[argc-1]);
   int c;

   fp = fopen(pathname,"r"); // read mode
 
   if( fp == NULL )
   {
      perror("Error while opening the file.\n");
      exit(EXIT_FAILURE);
   }
 
   printf("il numero di elementi nella colonna %d del file %s sono:\n",n,pathname);
 
  while ((c= getc(fp)) != EOF) {
        if ((carattere[1] = c) == '\n')
		contacolonna=0;      
    else
	contacolonna++;
	if(contacolonna==n){
		contachar++;
	}

}	
	printf("%d\n",contachar);
   fclose(fp);
   return 0;
}


Soluzione di F.Mastromarino e LorenzoV

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

int main(int argc, char *argv[]){
	int cont=0; int c; int colonna=atoi(argv[1]); int cont2=0;
	char *path="/home/francesco/Scrivania/stampa.txt";
	int fd=open(path, O_RDONLY, 0664); //0664 sono i permessi per la sola lettura
	fd=dup2(fd, STDIN_FILENO); //file stampa.txt come standard input
	struct stat buf;
	if(lstat(path, &buf)<0 && (buf.st_mode & S_IFMT)!=S_IFREG) // il campo st_mode indica il tipo di file e la costante S_IFREG 
//contiene il valore di un file regolare(0100000), S_IFMT è la maschera di bit usata per controllare il tipo di file
		return(-1);
	do{
		cont=0;
		do{
			
			c=getchar(); // legge un carattere da file e lo ritorna come un intero
			if(c!= EOF && (c>127 || c<1)){ // controllo se è un file ASCII
				printf("Non regolare\n");
			return(-1);
		}
			cont++;
			if(cont==colonna) cont2++;
		}while(c!='\n' && c!=EOF);
	}while(c!=EOF); // EOF è l'ultimo carattere del file da leggere
	printf("%d\n", cont2);
	close(fd);
	return(0);
}

--F.Mastromarino (talk) 11:14, 17 March 2015 (CET)

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()