Difference between revisions of "ProvaPratica 2014.01.23"
Jump to navigation
Jump to search
m (Eliminate indicazioni inutili) |
m (Aggiunta soluzione di ababa) |
||
(One intermediate revision by the same user not shown) | |||
Line 129: | Line 129: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | ===Soluzione di Stefano Zaniboni=== | ||
+ | <source lang="C"> | ||
+ | #define _GNU_SOURCE | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | #include <sys/types.h> | ||
+ | #include <error.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <unistd.h> | ||
+ | #include <sys/stat.h> | ||
+ | #include <fcntl.h> | ||
+ | |||
+ | int isRegular(const char *path){ /*controllo se il file e' regolare*/ | ||
+ | struct stat path_stat; | ||
+ | lstat(path, &path_stat); | ||
+ | return S_ISREG(path_stat.st_mode); | ||
+ | } | ||
+ | int main(int argc, char *argv[]){ | ||
+ | FILE *fp; | ||
+ | int status=0; | ||
+ | char *line=NULL; | ||
+ | size_t len=0; | ||
+ | int line_to_count=0; | ||
+ | ssize_t read; | ||
+ | int i=1; | ||
+ | |||
+ | if(argc != 3){ | ||
+ | fprintf(stderr, "no such arguments \n"); | ||
+ | exit(1); | ||
+ | } | ||
+ | line_to_count=atoi(argv[2]); | ||
+ | if(!(status=isRegular(argv[1]))){ | ||
+ | printf("error not regular file\n"); | ||
+ | exit(EXIT_FAILURE); | ||
+ | } | ||
+ | fp=fopen(argv[1], "r"); | ||
+ | if(fp==NULL){ | ||
+ | exit(EXIT_FAILURE); | ||
+ | } | ||
+ | while((read=getline(&line,&len,fp)) != -1){ | ||
+ | if(i==line_to_count){ | ||
+ | printf("retrived line of lenght %zu: \n",i, read); | ||
+ | printf("%s\n", line); | ||
+ | break; | ||
+ | } | ||
+ | i=i+1; | ||
+ | } | ||
+ | free(line); | ||
+ | exit(EXIT_SUCCESS); | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Codice scritto e caricato al confine di Stato Italia - Austria | ||
+ | |||
+ | === Soluzione di ababa === | ||
+ | |||
+ | Parte comune. | ||
+ | <source lang="c"> | ||
+ | #include <sys/types.h> | ||
+ | #include <sys/stat.h> | ||
+ | #include <unistd.h> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <error.h> | ||
+ | #include <fcntl.h> | ||
+ | #include <string.h> | ||
+ | |||
+ | int main(int argc, char *argv[]){ | ||
+ | int nriga=atoi(argv[2]); | ||
+ | /*controllo che siano stati passati 3 parametri alla funzione (la funzione stessa, il path, e l'intero*/ | ||
+ | if(argc==3){ | ||
+ | fprintf(stderr, "numero argomenti sbagliati \n"); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | /*controllo di aver aperto il file (e di conseguenza che il secondo parametro sia il path di un file)*/ | ||
+ | char *path; | ||
+ | path=argv[1]; | ||
+ | FILE *fd; | ||
+ | fd=fopen(path,"r"); | ||
+ | if (fd==NULL){ | ||
+ | fprintf(stderr, "file non aperto correttamente\n"); | ||
+ | exit(2); | ||
+ | } | ||
+ | |||
+ | /*controllo che il file sia regolare*/ | ||
+ | struct stat buf; | ||
+ | lstat(path,&buf); | ||
+ | if (!(S_ISREG(buf.st_mode))){ | ||
+ | fprintf(stderr, "file non regolare\n"); | ||
+ | exit(3); | ||
+ | } | ||
+ | </source> | ||
+ | Primo modo | ||
+ | <source lang="c"> | ||
+ | /*inizio a scorrere il file finche non mi posiziono sulla riga giusta*/ | ||
+ | int contrighe=0, contchar=0, c,cha=(int)'\n'; | ||
+ | |||
+ | while (((c=getc(fd))!=EOF)&&(contrighe<=nriga)) { | ||
+ | |||
+ | if (c==cha){ | ||
+ | contrighe++; | ||
+ | } | ||
+ | |||
+ | if ((contrighe==nriga)&&(cha!=c)){ | ||
+ | contchar++; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | contchar--; | ||
+ | printf("il numero di caratteri nella riga sono:%d",contchar); | ||
+ | fclose(fd); | ||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Secondo modo. | ||
+ | |||
+ | <source lang="c"> | ||
+ | /*inizio a scorrere il file finché non mi posiziono sulla riga giusta*/ | ||
+ | char *line=NULL; | ||
+ | int i, contchar; | ||
+ | size_t boh=0; | ||
+ | for (i=0;i<nriga;i++){ | ||
+ | getline(&line,&boh,fd); | ||
+ | free(line); | ||
+ | line=NULL; | ||
+ | } | ||
+ | getline(&line,&boh,fd); | ||
+ | contchar=strlen(line)-1; | ||
+ | printf("il numero di caratteri nella riga sono: %d\n",contchar); | ||
+ | fclose(fd); | ||
+ | return 0; | ||
+ | </source> | ||
+ | |||
==Esercizio 2== | ==Esercizio 2== |
Latest revision as of 08:54, 9 May 2017
Esercizio 1
Soluzione di Pirata
/*
*Esercizio 1: Linguaggio C (obbligatorio): (20 punti)
*Scrivere un programma in C “linean” 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 riga 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
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#define BUFFSIZE 200
int istextfile( FILE *fd ){ //check if the file is a regular file of text,it means that every byte has a value between 1-127
int c;
while ( (c = getc ( fd ) ) != EOF && c <= 127 );
rewind(fd); //sets the file's cursor at the beginning,otherwise the linean program cannot find the line
return ( (c == EOF)? 1 : 0 );
}
void linean( char *path , int line ){
FILE *fd;
struct stat buf;
char bufline[BUFFSIZE];
char *res;
int n = line;
res = NULL;
lstat( path , &buf );
if ( S_ISREG( buf.st_mode ) )
{
fd = fopen( path , "r" );
if ( fd == NULL )
{
perror( "Error to open the file\n" );
exit(1);
}
if ( istextfile( fd ) )
{
while ( ( line > 0 ) ) //iterates until at the nline and when is reached then checks if the buffer contains something
{
res = fgets(bufline, BUFFSIZE , fd ); //every time the nline is buffered,when exits from the cicle, the buffer contains the nline
line--;
}
if ( res != NULL )
{
printf( "The file %s in line %d has : %d char\n" , path , n , ( strlen( bufline ) - 1 ) ); //strlen also consider the carriage return
}
else
printf( "Error: isn't possible to find the line\n" );
}
else
printf( "Error is not a regular file of text\n" );
fclose(fd);
}
else
printf( "The file %s isn't a regular file\n" , path );
}
int main( int argc , char *argv[] ){
int n = atoi( argv[2] );
linean( argv[1] , n );
return(0);
}
Soluzione di Coci
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define PATH_LEN 100
#define BUF_LEN 200
printLine(char *path, int n){
FILE* fd;
char line[BUF_LEN];
char* res;
fd = fopen(path, "r");
if (fd == NULL) {perror("Errore nell'apertura del file"); exit(1);}
while (n != 0) {
n--;
res = fgets(line, BUF_LEN, fd);
if (res == NULL) {perror("Errore nella fgets"); exit(1);}
}
printf("La riga richiesta del file %s ha %d caratteri.\n", path, (int) strlen(line)-1 );
fclose(fd);
}
int main(int argc, char* argv[]){
int n;
char path[PATH_LEN];
struct stat buf;
if (argc != 3) {printf("Inserisci due parametri\n"); exit(1);}
strcpy(path, argv[1]);
n = atoi(argv[2]);
lstat (path, &buf);
if (S_ISREG(buf.st_mode) != 0) printLine(path, n);
return 1;
}
Soluzione di Stefano Zaniboni
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <error.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int isRegular(const char *path){ /*controllo se il file e' regolare*/
struct stat path_stat;
lstat(path, &path_stat);
return S_ISREG(path_stat.st_mode);
}
int main(int argc, char *argv[]){
FILE *fp;
int status=0;
char *line=NULL;
size_t len=0;
int line_to_count=0;
ssize_t read;
int i=1;
if(argc != 3){
fprintf(stderr, "no such arguments \n");
exit(1);
}
line_to_count=atoi(argv[2]);
if(!(status=isRegular(argv[1]))){
printf("error not regular file\n");
exit(EXIT_FAILURE);
}
fp=fopen(argv[1], "r");
if(fp==NULL){
exit(EXIT_FAILURE);
}
while((read=getline(&line,&len,fp)) != -1){
if(i==line_to_count){
printf("retrived line of lenght %zu: \n",i, read);
printf("%s\n", line);
break;
}
i=i+1;
}
free(line);
exit(EXIT_SUCCESS);
}
Codice scritto e caricato al confine di Stato Italia - Austria
Soluzione di ababa
Parte comune.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[]){
int nriga=atoi(argv[2]);
/*controllo che siano stati passati 3 parametri alla funzione (la funzione stessa, il path, e l'intero*/
if(argc==3){
fprintf(stderr, "numero argomenti sbagliati \n");
exit(1);
}
/*controllo di aver aperto il file (e di conseguenza che il secondo parametro sia il path di un file)*/
char *path;
path=argv[1];
FILE *fd;
fd=fopen(path,"r");
if (fd==NULL){
fprintf(stderr, "file non aperto correttamente\n");
exit(2);
}
/*controllo che il file sia regolare*/
struct stat buf;
lstat(path,&buf);
if (!(S_ISREG(buf.st_mode))){
fprintf(stderr, "file non regolare\n");
exit(3);
}
Primo modo
/*inizio a scorrere il file finche non mi posiziono sulla riga giusta*/
int contrighe=0, contchar=0, c,cha=(int)'\n';
while (((c=getc(fd))!=EOF)&&(contrighe<=nriga)) {
if (c==cha){
contrighe++;
}
if ((contrighe==nriga)&&(cha!=c)){
contchar++;
}
}
contchar--;
printf("il numero di caratteri nella riga sono:%d",contchar);
fclose(fd);
return 0;
}
Secondo modo.
/*inizio a scorrere il file finché non mi posiziono sulla riga giusta*/
char *line=NULL;
int i, contchar;
size_t boh=0;
for (i=0;i<nriga;i++){
getline(&line,&boh,fd);
free(line);
line=NULL;
}
getline(&line,&boh,fd);
contchar=strlen(line)-1;
printf("il numero di caratteri nella riga sono: %d\n",contchar);
fclose(fd);
return 0;
Esercizio 2
Soluzione di Pirata
/*
*Esercizio 2: completamento (10 punti)
*Si scriva un programma C chiamato “lineandir”. Il risultato del programma, stampato su standard output, deve essere un solo
*numero intero: la somma del numero di caratteri presenti nelle n-me righe di tutti i file regolari, di testo, non nascosti (il primo
*carattere deve essere diverso da punto) della directory corrente.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <dirent.h>
#define BUFFSIZE 200
int istextfile( FILE *fd );
int linean( char *path , int line );
void lineandir( char *dir , int line );
void lineandir( char *dir , int line ){
int count , i;
int sumline;
struct dirent **de;
sumline = 0;
count = scandir( dir , &de , NULL , alphasort );
for ( i = 0 ; i < count ; i++ )
{
if ( de[i]->d_name[0] != '.' ) //doesn't consider the hidden files
sumline = sumline + linean( de[i]->d_name , line );
free(de[i]);
}
printf("The sum of char for every regular text file's nline in the current directory is: %d\n" , sumline );
free(de);
}
int istextfile( FILE *fd ){
int c;
while ( (c = getc ( fd ) ) != EOF && c <= 127 );
rewind(fd);
return ( (c == EOF)? 1 : 0 );
}
/*linean is modified so it can return the value of the char in the nline */
int linean( char *path , int line ){
FILE *fd;
struct stat buf;
char bufline[BUFFSIZE];
char *res;
int n = line;
res = NULL;
lstat( path , &buf );
if ( S_ISREG( buf.st_mode ) )
{
fd = fopen( path , "r" );
if ( fd == NULL )
{
perror( "Error to open the file\n" );
exit(1);
}
if ( istextfile( fd ) )
{
while ( ( line > 0 ) )
{
res = fgets(bufline, BUFFSIZE , fd );
line--;
}
if ( res != NULL )
{
return( ( strlen( bufline ) - 1 ) );
}
else
printf( "Error: isn't possible to find the line\n" );
}
else
printf( "Error is not a regular file of text\n" );
fclose(fd);
}
else
printf( "The file %s isn't a regular file\n" , path );
}
int main( int argc , char *argv[] ){
int n = atoi( argv[1] );
lineandir( "./" , n );
return(0);
}
Soluzione di Coci
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
#define PATH_LEN 100
#define BUF_LEN 200
int printLine(char *path, int n){
FILE* fd;
char line[BUF_LEN];
char* res;
fd = fopen(path, "r");
if (fd == NULL) {perror("Errore nell'apertura del file"); exit(1);}
while (n != 0) {
n--;
res = fgets(line, BUF_LEN, fd);
if (res == NULL) {perror("Errore nella fgets"); exit(1);}
}
printf("La riga richiesta del file %s ha %d caratteri.\n", path, (int) strlen(line)-1 );
fclose(fd);
return ((int) strlen(line)-1);
}
lineandir (char path[PATH_LEN], int line_num){
int i, ris, counter;
char nome[PATH_LEN];
struct dirent **namelist;
struct stat buf;
strcpy (nome, path);
counter = 0;
ris = scandir(path, &namelist, 0, alphasort);
if (ris < 0) {perror("scandir error:"); exit(1);}
else {
for(i=0; i<ris; i++){
if ( strncmp(namelist[i]->d_name, ".", 1) == 0) continue;
strcat(nome, namelist[i]->d_name);
lstat (nome, &buf);
/*se l'iesimo file è regolare, conto i caratteri*/
if (S_ISREG(buf.st_mode) != 0) counter += printLine(nome, line_num);
/*rimetto la radice del nome a "./"*/
strcpy (nome, path);
}
printf("la somma delle righe %d è %d\n", line_num, counter);
}
}
int main(int argc, char* argv[]){
int n;
if (argc != 2) {printf("Inserisci un parametro\n"); exit(1);}
n = atoi(argv[1]);
lineandir("./", n);
return 1;
}
Coci
Esercizio 3
Soluzione di Pirata
#Esercizio 3: Script bash o Python: (10 punti):
#Il comando che dovrete implementare come script shell o programma python e' updatedir. Updatedir prende due directorycome parametri.
#updatedir dira dirb deve copiare in dirb 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, il file deve essere copiato dalla dira alla dirb solo se i contenuti differiscono.
#! /bin/bash
for file in "$1"/*; do
if [[ -f $file ]] ; then #checks if the file is regular
thereisnotfile=1 #variable that identify if the file is also in dir2
for file2 in "$2"/*; do
if [[ -f $file2 ]] ; then
if [[ $file2 != $file ]] ; then #checks if the file is only in dir1 and not in dir2
continue
else
thereisnotfile=0 #the file is in both dir
fi
if [[ $thereisnotfile -eq 0 ]]; then
if [[ $(md5sum "$file") != $(md5sum "$file2") ]] ; then #checks if the file in dir1 is different of file in dir2 by md5sum
bn=$(basename "$file")
cp $file "$2"/"$bn"
thereisnotfile=2 #is set in this way for not continue to iterate
fi
fi
fi
done
if [[ $thereisnotfile -eq 1 ]]; then
bn=$(basename "$file")
cp $file "$2"/"$bn"
fi
fi
done
Pirata
Soluzione di Mrta
#!/bin/bash
function usage {
command=$(basename "$0")
echo "Usage: $command source destination"
exit 1
}
if [[ ! -d $1 ]]
then
echo "Source is not a dir"
usage
fi
if [[ ! -d $2 ]]
then
echo "Destination is not a dir"
usage
fi
find $1 -type f -print0 | while IFS= read -r -d $'\0' file; do
filename=$(basename "$file")
if [[ -f "$2$filename" ]]
then
cp "$file" "$2$filename"
else
if cmp -s "$file" "$2$filename"
then
/* Do nothing are the same */
else
cp "$file" "$2$filename"
fi
fi
done
Mrta
Soluzione di Claudio Kerov e Stefano Zaniboni
#!/usr/local/bin/python3
import os
import sys
import filecmp
import shutil
if not os.path.isdir(sys.argv[1]):
sys.exit(sys.argv[1]+" non è una directory!")
if not os.path.isdir(sys.argv[2]):
sys.exit(sys.argv[2]+" non è una directory!")
dir1= sys.argv[1]
dir2= sys.argv[2]
lista=[]
for path, dirnames, filenames in os.walk(dir2):
for filename in filenames:
if(os.path.isfile(dir2+filename)):
lista.append(filename)
for path, dirnames, filenames in os.walk(dir1):
for filename in filenames:
if(os.path.isfile(dir1+filename)):
if filename in lista:
if not filecmp.cmp(dir1+filename, dir2+filename):
shutil.copyfile(dir1+filename, dir2+filename)
print("Ho copiato",filename+"! (diff)")
else:
shutil.copy(dir1+filename, dir2)
print("Ho copiato", filename+"!")