Difference between revisions of "ProvaPratica 2009.02.12"
Jump to navigation
Jump to search
Stefano 92 (talk | contribs) |
m (Aggiunte soluzioni di altri studenti) |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | + | [http://www.cs.unibo.it/~renzo/so/pratiche/2009.02.12.pdf Link al testo] | |
== Esercizio 1 == | == Esercizio 1 == | ||
+ | ===Soluzione di Stefano92=== | ||
+ | <source lang="text"> | ||
+ | Scrivere un programma C denominato “invarg” che esegua il programma passato | ||
+ | come parametro invertendo gli argomenti. | ||
+ | Esempio: | ||
+ | invarg cat a b c | ||
+ | deve avere l'effetto di | ||
+ | cat c b a | ||
+ | </source> | ||
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
#include <stdio.h> | #include <stdio.h> | ||
Line 39: | Line 48: | ||
argc--; | argc--; | ||
execvp(argv[0],argv); | execvp(argv[0],argv); | ||
+ | //equivalentemente avrei potuto lanciare execvp(argv[1],argv+1) evitando di modificare argv[] | ||
return 0; | return 0; | ||
+ | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
stefano92 | stefano92 | ||
+ | |||
+ | ===Soluzione di Maldus=== | ||
+ | <source lang="c"> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | |||
+ | int main(int argc , char* argv[]){ | ||
+ | char *nargv[argc-1] ; /*nargv è il vettore degli argomenti da passare al programma da eseguire*/ | ||
+ | int i , j ; /*puntatori che scorrono, rispettivamente, argv ed nargv per riempire correttamente nargv*/ | ||
+ | nargv[0] = argv[1] ; /*il primo valore di nargv deve essere il programma chiamato, l'ultimo deve essere NULL*/ | ||
+ | nargv[argc-1] = NULL ; | ||
+ | for( i = argc - 1 , j = 1 ; i > 1 , j < (argc - 1) ; i-- , j++ ) nargv[j] = argv[i] ; /*metto in nargv (dal secondo elemento in poi) gli argomenti presenti | ||
+ | in argv in ordine invertito*/ | ||
+ | execvp( nargv[0] , nargv ) ; /*eseguo il programma (il cui nome è contenuto in nargv[0]) passandogli nargv come vettore di parametri*/ | ||
+ | fprintf( stderr , "programma errato\n" ) ; /*se ci troviamo in questo punto significa che la chiamata a execvp è fallita, probabilmente | ||
+ | perchè il programma indicato non è stato trovato*/ | ||
+ | exit(1) ; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ===Soluzione di Eddy=== | ||
+ | <source lang="c"> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <errno.h> | ||
+ | |||
+ | void scambia_ordine(int argc, char **argv, int j); | ||
+ | |||
+ | int main(int argc , char* argv[]) | ||
+ | { | ||
+ | if (argc < 2) return 2; | ||
+ | argv++; argc--; | ||
+ | scambia_ordine(argc, argv, 1); | ||
+ | execvp(argv[0], argv); | ||
+ | perror("execvp"); | ||
+ | return 3; | ||
+ | } | ||
+ | |||
+ | /* piccola funzione ricorsiva che: | ||
+ | * -memorizza in tmp gli argomenti dalla fine | ||
+ | * -assegna ad argv in ordine inverso | ||
+ | * | ||
+ | * non scambia il primo argomento | ||
+ | */ | ||
+ | void scambia_ordine(int argc, char **argv, int j) | ||
+ | { | ||
+ | char *tmp; | ||
+ | if (argc > 1){ | ||
+ | tmp = argv[argc-1]; | ||
+ | scambia_ordine (argc-1, argv, j+1); | ||
+ | argv[j]=tmp; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </source> | ||
+ | [[User:Eddy|Eddy]] ([[User talk:Eddy|talk]]) 21:00 Saturday, 22 November 2014 (CET) | ||
+ | |||
+ | ===Soluzione di GFede=== | ||
+ | <source lang="c"> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | #include <errno.h> | ||
+ | |||
+ | void scambia(int offset, int argc, char* argv[]); | ||
+ | |||
+ | int main(int argc, char* argv[]) | ||
+ | { | ||
+ | if(argc <= 1) | ||
+ | { | ||
+ | printf("Usage: invarg.exe command [arguments...]\n"); | ||
+ | return 2; | ||
+ | } | ||
+ | scambia(2, argc - 1, argv); | ||
+ | |||
+ | execvp(argv[1], argv + 1); | ||
+ | perror("execvp"); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Scambia le stringhe all'interno dell'array | ||
+ | * void scambia | ||
+ | * int offset Indice da cui iniziare a scambiare | ||
+ | * int argc Numero di valori nell'array (Compreso l'offset) | ||
+ | * char* argv[] array di stringhe da scambiare | ||
+ | */ | ||
+ | void scambia(int offset, int argc, char* argv[]) | ||
+ | { | ||
+ | int i; | ||
+ | char* tmp; | ||
+ | for( i = offset; i < argc - i + offset; i++ ) | ||
+ | { | ||
+ | tmp = argv[i]; | ||
+ | argv[i] = argv[argc - i + offset]; | ||
+ | argv[argc - i + offset] = tmp; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ===Soluzione di LorenzoV=== | ||
+ | <source lang="c"> | ||
+ | #include <stdlib.h> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | void swap(char **p, char **q){ // La swap modifica solo i puntatori | ||
+ | char *tmp; | ||
+ | tmp=*p; | ||
+ | *p=*q; | ||
+ | *q=tmp; | ||
+ | } | ||
+ | |||
+ | int main(int argc, char* argv[]){ | ||
+ | char **begin, **end; | ||
+ | if (argc<3){ | ||
+ | fprintf(stderr, "Usage:\n\t%s command ...arguments...\n", argv[0]); | ||
+ | exit(1); | ||
+ | } | ||
+ | begin=argv+2; | ||
+ | end=argv+argc-1; | ||
+ | while (begin<end){ // Inverte i parametri passati al comando | ||
+ | swap(begin, end); | ||
+ | begin++; | ||
+ | end--; | ||
+ | } | ||
+ | execvp(argv[1], argv+1); | ||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | --[[User:LorenzoV|LorenzoV]] ([[User talk:LorenzoV|talk]]) 18:35, 25 November 2014 (CET) | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===Soluzione di BoldrinD=== | ||
+ | <source lang="c"> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | #include <errno.h> | ||
+ | |||
+ | void invarg(int Qparametri, char* Rargv[], char* argv[]); | ||
+ | |||
+ | int main(int argc, char* argv[]){ | ||
+ | int Qparametri=argc-1; | ||
+ | char *Rargv[Qparametri]; | ||
+ | invarg(Qparametri, Rargv, argv); | ||
+ | printf("%s\n","il nuovo vettore dei parametri è stato creato con successo"); | ||
+ | execvp(Rargv[0], Rargv); | ||
+ | perror("execvp"); | ||
+ | return 1; | ||
+ | |||
+ | } | ||
+ | |||
+ | void invarg(int Qparametri, char* Rargv[], char* argv[]){ | ||
+ | Rargv[0]=argv[1]; | ||
+ | Rargv[Qparametri]=NULL; | ||
+ | int i=2; | ||
+ | while(argv[i]!=NULL){ | ||
+ | Rargv[Qparametri-1]=(argv[i]); | ||
+ | i++; | ||
+ | Qparametri--; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </source> | ||
+ | |||
+ | |||
+ | ===Soluzione di AleZ=== | ||
+ | <source lang="c"> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | |||
+ | int main (int argc, char* argv[]) { | ||
+ | if (argc == 1) { // Non è stato passato alcun comando per la execvp | ||
+ | fprintf(stderr, "Error: Segmentation fault\nUsage: [command] [arguments...]\n"); | ||
+ | return(EXIT_FAILURE); | ||
+ | } | ||
+ | char* tmp[argc]; // vettore che conterrà gli argomenti scambiati | ||
+ | int i = 0; | ||
+ | tmp[0] = argv[1]; // per convenzione il primo argomento è il programma chiamato | ||
+ | tmp[argc-1] = (char*)NULL; // come da manuale | ||
+ | for (i = argc-2; i > 0; i--) tmp[i] = argv[(argc-i)]; // inverto gli argomenti | ||
+ | execvp(tmp[0], tmp); | ||
+ | fprintf(stderr, "%s: command not found\n", argv[1]); //execvp ha fallito | ||
+ | return(EXIT_FAILURE); | ||
+ | } | ||
+ | </source> | ||
+ | --[[User:Ale|Ale]] ([[User talk:Ale|talk]]) 20:39, 1 December 2014 (CET) | ||
+ | |||
+ | ==Esercizio 2== | ||
+ | ===Soluzione di Dado e Pierg=== | ||
+ | <source lang="text"> | ||
+ | Scrivere un programma in linguaggio C che crei due named pipe (passate per argomento), le apra in lettura e | ||
+ | e copi in standard output i dati via via disponibili da ogni pipe. | ||
+ | Test di funzionamento: aprire tre finestre di emulazione terminale. Nella prima lanciare: mergepipe p1 p2, nella seconda: | ||
+ | cat >p1, nella terza cat>p2. | ||
+ | Tutto cio' che scriverete o nella seconda o nella terza finestra deve comparire nella prima. | ||
+ | </source> | ||
+ | <source lang="c"> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <poll.h> | ||
+ | #include <sys/types.h> | ||
+ | #include <sys/stat.h> | ||
+ | #include <fcntl.h> | ||
+ | |||
+ | #define MAX 2048 | ||
+ | |||
+ | int main (int argc, char *argv[]) { | ||
+ | if (argc < 3) { | ||
+ | perror("Argomenti sbagliati"); | ||
+ | } | ||
+ | else { | ||
+ | struct pollfd pino [2]; | ||
+ | nfds_t n = 2; | ||
+ | char buf[MAX]; | ||
+ | |||
+ | mkfifo(argv[1], 0666); | ||
+ | mkfifo(argv[2], 0666); | ||
+ | pino[0].fd = open(argv[1], O_RDONLY | O_NONBLOCK); | ||
+ | pino[1].fd = open(argv[2], O_RDONLY | O_NONBLOCK); | ||
+ | pino[0].events = POLLIN; | ||
+ | pino[1].events = POLLIN; | ||
+ | |||
+ | while(1) { | ||
+ | int ret = poll(pino, n, 100); | ||
+ | if (ret == 1) { | ||
+ | if (pino[0].revents == POLLIN) { | ||
+ | ssize_t x = read(pino[0].fd, buf, MAX); | ||
+ | buf[x+1] = '\0'; | ||
+ | printf("%s", buf); | ||
+ | pino[0].revents = 0; | ||
+ | } | ||
+ | else { | ||
+ | ssize_t x = read(pino[1].fd, buf, MAX); | ||
+ | buf[x+1] = '\0'; | ||
+ | printf("%s", buf); | ||
+ | pino[1].revents = 0; | ||
+ | } | ||
+ | } | ||
+ | else if (ret == 2) { | ||
+ | ssize_t x = read(pino[0].fd, buf, MAX); | ||
+ | buf[x+1] = '\0'; | ||
+ | printf("%s", buf); | ||
+ | pino[0].revents = 0; | ||
+ | x = read(pino[1].fd, buf, MAX); | ||
+ | buf[x+1] = '\0'; | ||
+ | printf("%s", buf); | ||
+ | pino[1].revents = 0; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> |
Latest revision as of 08:44, 10 May 2017
Esercizio 1
Soluzione di Stefano92
Scrivere un programma C denominato “invarg” che esegua il programma passato
come parametro invertendo gli argomenti.
Esempio:
invarg cat a b c
deve avere l'effetto di
cat c b a
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void usage()
{
printf("usage: ./invarg.out EXEC_NAME [ARG1] [ARG2] ... [ARGN]\n");
}
int main(int argc,char* argv[])
{
char* tmp_i,*tmp_x;
int x=(argc-1),i=2;
if (argc<2)
{
usage();
return(1);
}
while(i<x)
{
tmp_i=argv[i];
tmp_x=argv[x];
argv[i]=tmp_x;
argv[x]=tmp_i;
i++;
x--;
}
for(i=0;i<argc-1;i++)
argv[i]=argv[i+1];
argv[argc-1]=NULL;
argc--;
execvp(argv[0],argv);
//equivalentemente avrei potuto lanciare execvp(argv[1],argv+1) evitando di modificare argv[]
return 0;
}
stefano92
Soluzione di Maldus
#include <stdio.h>
#include <stdlib.h>
int main(int argc , char* argv[]){
char *nargv[argc-1] ; /*nargv è il vettore degli argomenti da passare al programma da eseguire*/
int i , j ; /*puntatori che scorrono, rispettivamente, argv ed nargv per riempire correttamente nargv*/
nargv[0] = argv[1] ; /*il primo valore di nargv deve essere il programma chiamato, l'ultimo deve essere NULL*/
nargv[argc-1] = NULL ;
for( i = argc - 1 , j = 1 ; i > 1 , j < (argc - 1) ; i-- , j++ ) nargv[j] = argv[i] ; /*metto in nargv (dal secondo elemento in poi) gli argomenti presenti
in argv in ordine invertito*/
execvp( nargv[0] , nargv ) ; /*eseguo il programma (il cui nome è contenuto in nargv[0]) passandogli nargv come vettore di parametri*/
fprintf( stderr , "programma errato\n" ) ; /*se ci troviamo in questo punto significa che la chiamata a execvp è fallita, probabilmente
perchè il programma indicato non è stato trovato*/
exit(1) ;
}
Soluzione di Eddy
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
void scambia_ordine(int argc, char **argv, int j);
int main(int argc , char* argv[])
{
if (argc < 2) return 2;
argv++; argc--;
scambia_ordine(argc, argv, 1);
execvp(argv[0], argv);
perror("execvp");
return 3;
}
/* piccola funzione ricorsiva che:
* -memorizza in tmp gli argomenti dalla fine
* -assegna ad argv in ordine inverso
*
* non scambia il primo argomento
*/
void scambia_ordine(int argc, char **argv, int j)
{
char *tmp;
if (argc > 1){
tmp = argv[argc-1];
scambia_ordine (argc-1, argv, j+1);
argv[j]=tmp;
}
}
Eddy (talk) 21:00 Saturday, 22 November 2014 (CET)
Soluzione di GFede
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
void scambia(int offset, int argc, char* argv[]);
int main(int argc, char* argv[])
{
if(argc <= 1)
{
printf("Usage: invarg.exe command [arguments...]\n");
return 2;
}
scambia(2, argc - 1, argv);
execvp(argv[1], argv + 1);
perror("execvp");
return 1;
}
/**
* Scambia le stringhe all'interno dell'array
* void scambia
* int offset Indice da cui iniziare a scambiare
* int argc Numero di valori nell'array (Compreso l'offset)
* char* argv[] array di stringhe da scambiare
*/
void scambia(int offset, int argc, char* argv[])
{
int i;
char* tmp;
for( i = offset; i < argc - i + offset; i++ )
{
tmp = argv[i];
argv[i] = argv[argc - i + offset];
argv[argc - i + offset] = tmp;
}
}
Soluzione di LorenzoV
#include <stdlib.h>
#include <stdio.h>
void swap(char **p, char **q){ // La swap modifica solo i puntatori
char *tmp;
tmp=*p;
*p=*q;
*q=tmp;
}
int main(int argc, char* argv[]){
char **begin, **end;
if (argc<3){
fprintf(stderr, "Usage:\n\t%s command ...arguments...\n", argv[0]);
exit(1);
}
begin=argv+2;
end=argv+argc-1;
while (begin<end){ // Inverte i parametri passati al comando
swap(begin, end);
begin++;
end--;
}
execvp(argv[1], argv+1);
return 0;
}
--LorenzoV (talk) 18:35, 25 November 2014 (CET)
Soluzione di BoldrinD
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
void invarg(int Qparametri, char* Rargv[], char* argv[]);
int main(int argc, char* argv[]){
int Qparametri=argc-1;
char *Rargv[Qparametri];
invarg(Qparametri, Rargv, argv);
printf("%s\n","il nuovo vettore dei parametri è stato creato con successo");
execvp(Rargv[0], Rargv);
perror("execvp");
return 1;
}
void invarg(int Qparametri, char* Rargv[], char* argv[]){
Rargv[0]=argv[1];
Rargv[Qparametri]=NULL;
int i=2;
while(argv[i]!=NULL){
Rargv[Qparametri-1]=(argv[i]);
i++;
Qparametri--;
}
}
Soluzione di AleZ
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char* argv[]) {
if (argc == 1) { // Non è stato passato alcun comando per la execvp
fprintf(stderr, "Error: Segmentation fault\nUsage: [command] [arguments...]\n");
return(EXIT_FAILURE);
}
char* tmp[argc]; // vettore che conterrà gli argomenti scambiati
int i = 0;
tmp[0] = argv[1]; // per convenzione il primo argomento è il programma chiamato
tmp[argc-1] = (char*)NULL; // come da manuale
for (i = argc-2; i > 0; i--) tmp[i] = argv[(argc-i)]; // inverto gli argomenti
execvp(tmp[0], tmp);
fprintf(stderr, "%s: command not found\n", argv[1]); //execvp ha fallito
return(EXIT_FAILURE);
}
--Ale (talk) 20:39, 1 December 2014 (CET)
Esercizio 2
Soluzione di Dado e Pierg
Scrivere un programma in linguaggio C che crei due named pipe (passate per argomento), le apra in lettura e
e copi in standard output i dati via via disponibili da ogni pipe.
Test di funzionamento: aprire tre finestre di emulazione terminale. Nella prima lanciare: mergepipe p1 p2, nella seconda:
cat >p1, nella terza cat>p2.
Tutto cio' che scriverete o nella seconda o nella terza finestra deve comparire nella prima.
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAX 2048
int main (int argc, char *argv[]) {
if (argc < 3) {
perror("Argomenti sbagliati");
}
else {
struct pollfd pino [2];
nfds_t n = 2;
char buf[MAX];
mkfifo(argv[1], 0666);
mkfifo(argv[2], 0666);
pino[0].fd = open(argv[1], O_RDONLY | O_NONBLOCK);
pino[1].fd = open(argv[2], O_RDONLY | O_NONBLOCK);
pino[0].events = POLLIN;
pino[1].events = POLLIN;
while(1) {
int ret = poll(pino, n, 100);
if (ret == 1) {
if (pino[0].revents == POLLIN) {
ssize_t x = read(pino[0].fd, buf, MAX);
buf[x+1] = '\0';
printf("%s", buf);
pino[0].revents = 0;
}
else {
ssize_t x = read(pino[1].fd, buf, MAX);
buf[x+1] = '\0';
printf("%s", buf);
pino[1].revents = 0;
}
}
else if (ret == 2) {
ssize_t x = read(pino[0].fd, buf, MAX);
buf[x+1] = '\0';
printf("%s", buf);
pino[0].revents = 0;
x = read(pino[1].fd, buf, MAX);
buf[x+1] = '\0';
printf("%s", buf);
pino[1].revents = 0;
}
}
}
}