Repository 32bit  Forum
Repository 64bit  Wiki

Nuova piccola applicazione

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

Re: Nuova piccola applicazione

Messaggioda j0kers » dom giu 13, 2010 13:42

Ok 8)
Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda Blallo » dom giu 13, 2010 13:51

la soluzione che ti ha dato spina è un esempio
semplicemente al posto dei char "statici" puoi dargli in pasto un file di testo, semplicemente
Io sono il detective Arsenio Magret, e porto sempre la camicia TATUATA!
Avatar utente
Blallo
Packager
Packager
 
Messaggi: 3226
Iscritto il: ven ott 12, 2007 10:37
Località: Torino / Torremaggiore (FG)
Nome Cognome: Savino Liguori
Slackware: 14.1 / 12.2
Kernel: 3.12.2-ck
Desktop: Openbox

Re: Nuova piccola applicazione

Messaggioda j0kers » dom giu 13, 2010 13:54

Certo però si aggiunge comunque altro codice e altre variabili.
comunque ci sono milioni di soluzioni per giungere alla medesima soluzione.
Dipende poi dal programmatore
Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda Blallo » dom giu 13, 2010 13:56

j0kers ha scritto:Certo però si aggiunge comunque altro codice e altre variabili.
comunque ci sono milioni di soluzioni per giungere alla medesima soluzione.
Dipende poi dal programmatore

e allora?
meglio "tanto" codice (che così tanto non è, fidati) e compili una volta sola o modificare e ricompilare ogni volta?
è più una questione di atteggiamento
se ora fai così, se fai robe più grosse, non credo ti converrà tanto modificare e ricompilare ogni volta
oltre a far divenire il programma un "obbrobrio"
Io sono il detective Arsenio Magret, e porto sempre la camicia TATUATA!
Avatar utente
Blallo
Packager
Packager
 
Messaggi: 3226
Iscritto il: ven ott 12, 2007 10:37
Località: Torino / Torremaggiore (FG)
Nome Cognome: Savino Liguori
Slackware: 14.1 / 12.2
Kernel: 3.12.2-ck
Desktop: Openbox

Re: Nuova piccola applicazione

Messaggioda j0kers » dom giu 13, 2010 13:57

Yep :D
Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda Mario Vanoni » dom giu 13, 2010 14:32

j0kers ha scritto:Oppure
Codice: Seleziona tutto
if( (fp=fopen("proc","r"))==NULL)
      exit(fprintf(stderr, "Errore apertura file!\n"));

Giusto ?

Ancora piu` short:
Codice: Seleziona tutto
if(! (fp = fopen("proc","r")))
      exit(fprintf(stderr, "Errore apertura file!\n"));

Come dice giustamente Emanuele,
gli exit code possono servire per individuare il posto del fallimento,
con un programma semplice pero` basta zero o non zero,
soprattutto se il messaggio d'errore e` molto chiaro!
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: Nuova piccola applicazione

Messaggioda targzeta » dom giu 13, 2010 21:25

Mario Vanoni ha scritto:...gli exit code possono servire per individuare il posto del fallimento,
con un programma semplice pero` basta zero o non zero,
soprattutto se il messaggio d'errore e` molto chiaro!

Beh questo non è proprio vero, il codice di errore generalmente non serve all'utente ma ad un comando che deve comportarsi in un modo piuttosto che in un altro a seconda di questo codice. Per l'utente il software potrebbe anche terminare con 'return 0' se prima gli dice che tipo di errore è avvenuto, tanto per lui è chiaro cos'è successo. Però l'stderr può comunque essere ridiretto verso /dev/null e controllare solo il codice di ritorno. Un esempio tra tutti è lo script di avvio della Slackware (rc.S):
Codice: Seleziona tutto
...
  if [ ! -r /etc/fastboot ]; then
    /sbin/fsck $FORCEFSCK -C -a /
    RETVAL=$?
  fi
  if [ $RETVAL -ge 2 ]; then
    if [ $RETVAL -ge 4 ]; then
      echo "*** An error occurred during the root filesystem check. ***"
      ...
    else # With an error code of 2 or 3, reboot the machine automatically:
...
Allo script non interessa minimamente l'output del comando fsck ma gli interessa invece il codice di ritorno per capire se è andato tutto bene o cosa è successo in dettaglio.

Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6176
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Nuova piccola applicazione

Messaggioda gallows » dom giu 13, 2010 22:08

Mario Vanoni ha scritto:
j0kers ha scritto:Oppure
Codice: Seleziona tutto
if( (fp=fopen("proc","r"))==NULL)
      exit(fprintf(stderr, "Errore apertura file!\n"));

Giusto ?

Ancora piu` short:
Codice: Seleziona tutto
if(! (fp = fopen("proc","r")))
      exit(fprintf(stderr, "Errore apertura file!\n"));



Programs should be written for people to read, and only incidentally for machines to execute.

Anche se sono programmi giocattolo e - suppongo - i primi che scrivi cerca sempre di mantenere una certa disciplina. Avere l'abitudine di scrivere buon codice è importante. Quando avrai a che fare con programmi (comunque piccoli) da migliaia di righe di codice e devi sistemare qualcosa, leggere questi "trucchetti" risulterà piuttosto irritante!
(Per buon codice indendo anche valori di uscita decenti, se poi è un PoC usa assert()).

ps. dai un'occhiata a errno.h, perror() et similia o alle funzioni bsd in err.h
Avatar utente
gallows
Staff
Staff
 
Messaggi: 3466
Iscritto il: dom set 19, 2004 23:00
Località: Palermo
Kernel: FreeBSD 8.0-RELEASE-p3
Desktop: ratpoison

Re: Nuova piccola applicazione

Messaggioda masalapianta » lun giu 14, 2010 16:21

:fuori: :banghead: :banghead: :banghead: :pottytrain5:
a parte gli orrori che ti han gia fatto notare, in una manciata di righe di codice abbiamo, non uno, ma ben due overflow sullo stack, dipendenti dalla dimensione di argv[1] e di quello che c'è nel file "proc", se hai a che fare con stringhe di cui non conosci a priori la lunghezza valuta la possibilità di allocare dinamicamente con malloc e socie, oppure se vuoi porre a priori un limite assicurati di controllare quanta roba scrivi ed eventualmente gestisci l'eccezione (anzichè troncare la stringa e proseguire come nulla fosse); usi una variabile di appoggio "lettura_file" non si capisce per quale motivo (porcata per porcata a sto punto anzichè fare strncpy dal buffer della fgets a lettura_file e poi strcat da lettura_file a comando a sto punto fai direttamente strncat dal buffer della fgets a comando); evita i commenti con //, non sono ansi/c89; includi stdlib.h senza motivo.
Apro una parentesi sulla programmazione pseudo-sicura: non usate MAI roba come strcat e compagnia cantante se non avete la certezza che sia stato fatto un controllo a monte; per la manipolazione delle stringhe esistono alternative sicure come le strl* bsd, l'approccio bernsteiniano con alloc/stralloc, ecc..
Tornando a te, è evidente che stai cominciando a programmare senza alcun metodo, verosilmilmente hai letto qualche pagina di un tutorial e ti sei buttato a scriver codice senza aver prima acquisito le nozioni che quel codice richiede per essere scritto; con linguaggi ad alto livello (perl, php, ecc..), questo tipo di approccio, seppure porti a risultati mediocri, può essere intrapreso, con il C no; procurati un buon libro (consiglio Deitel&Deitel e K&R, il primo è più didattico ma molto dispersivo, il secondo è meno dispersivo ma meno didattico) e inizia a studiare, scrivi tanto codice, ma scrivilo di pari passo con la teoria studiata.

Riguardo il vanoniano exit, usando come codice d'uscita l'int tornato dalla fprintf, stendo un velo pietoso, per ottimi motivi esistono metodi standard (vedi post di gallows) per la gestione degli errori e per l'uso di particolari exit code in caso di errore.
Avatar utente
masalapianta
Iper Master
Iper Master
 
Messaggi: 2775
Iscritto il: dom lug 24, 2005 23:00
Località: Roma
Nome Cognome: famoso porco
Kernel: uname -r
Desktop: awesome
Distribuzione: Debian

Re: Nuova piccola applicazione

Messaggioda metrofox » lun giu 14, 2010 16:57

masalapianta ha scritto::fuori: :banghead: :banghead: :banghead: :pottytrain5:
a parte gli orrori che ti han gia fatto notare, in una manciata di righe di codice abbiamo, non uno, ma ben due overflow sullo stack, dipendenti dalla dimensione di argv[1] e di quello che c'è nel file "proc", se hai a che fare con stringhe di cui non conosci a priori la lunghezza valuta la possibilità di allocare dinamicamente con malloc e socie, oppure se vuoi porre a priori un limite assicurati di controllare quanta roba scrivi ed eventualmente gestisci l'eccezione (anzichè troncare la stringa e proseguire come nulla fosse); usi una variabile di appoggio "lettura_file" non si capisce per quale motivo (porcata per porcata a sto punto anzichè fare strncpy dal buffer della fgets a lettura_file e poi strcat da lettura_file a comando a sto punto fai direttamente strncat dal buffer della fgets a comando); evita i commenti con //, non sono ansi/c89; includi stdlib.h senza motivo.
Apro una parentesi sulla programmazione pseudo-sicura: non usate MAI roba come strcat e compagnia cantante se non avete la certezza che sia stato fatto un controllo a monte; per la manipolazione delle stringhe esistono alternative sicure come le strl* bsd, l'approccio bernsteiniano con alloc/stralloc, ecc..
Tornando a te, è evidente che stai cominciando a programmare senza alcun metodo, verosilmilmente hai letto qualche pagina di un tutorial e ti sei buttato a scriver codice senza aver prima acquisito le nozioni che quel codice richiede per essere scritto; con linguaggi ad alto livello (perl, php, ecc..), questo tipo di approccio, seppure porti a risultati mediocri, può essere intrapreso, con il C no; procurati un buon libro (consiglio Deitel&Deitel e K&R, il primo è più didattico ma molto dispersivo, il secondo è meno dispersivo ma meno didattico) e inizia a studiare, scrivi tanto codice, ma scrivilo di pari passo con la teoria studiata.

Riguardo il vanoniano exit, usando come codice d'uscita l'int tornato dalla fprintf, stendo un velo pietoso, per ottimi motivi esistono metodi standard (vedi post di gallows) per la gestione degli errori e per l'uso di particolari exit code in caso di errore.


stdlib.h gli serve in caso dovesse usare gli exit, come consigliato da vanoni, se non deve usarli allora sarebbe inutile dare una direttiva al preprocessore che non serve a nulla. Comunque dai, siate duri ma non troppo col ragazzo, magari ha veramente cominciato a programmare da poco e senza metodo, gliel'avete fatto notare ma mi sa che nonostante ciò che gli avete detto(e non 1 volta, ma 100) gli stiate facendo anche passare la voglia.
Avatar utente
metrofox
Linux 2.6
Linux 2.6
 
Messaggi: 758
Iscritto il: gio ago 07, 2008 11:29
Slackware: slackware64-current
Kernel: 3.4.4-ck3
Desktop: FluxBox-1.3.1
Distribuzione: FreeBSD-8.1(amd64)

Re: Nuova piccola applicazione

Messaggioda j0kers » lun giu 14, 2010 17:10

Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    FILE *fp;       
    char *cmd;   
    char *buffer;
    int buff_size=128;


    if((fp=fopen("proc","r"))==NULL)
        exit(fprintf(stderr, "Open file error!\n"));

    if( (cmd=malloc(buff_size))==NULL || (buffer=malloc(buff_size))==NULL)
        exit(fprintf(stderr,"Error allocate %s or %s into memory!\n",cmd,buffer));

    if(argc==2){
        strcpy(cmd,"/bin/ps ");
        strcat(cmd,argv[1]);
        strcat(cmd," | grep -v");
    }else
        strcpy(cmd,"/bin/ps | grep -v");

    while(fgets(buffer,buff_size,fp)){
        if ((cmd = realloc(cmd, buff_size *= 2)) == NULL)
            exit(fprintf(stderr,"Error allocate %s into memory!\n",cmd));
        strcat(cmd," -e ");
        strncat(cmd,buffer,strlen(buffer)-1);
    }

    system(cmd);

    return 0;
}

Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda metrofox » lun giu 14, 2010 17:23

Io direi poi di liberare il puntatore.
Avatar utente
metrofox
Linux 2.6
Linux 2.6
 
Messaggi: 758
Iscritto il: gio ago 07, 2008 11:29
Slackware: slackware64-current
Kernel: 3.4.4-ck3
Desktop: FluxBox-1.3.1
Distribuzione: FreeBSD-8.1(amd64)

Re: Nuova piccola applicazione

Messaggioda j0kers » lun giu 14, 2010 17:30

Mi sono dimenticato anche di chiudere il file :D Errori di svista purtroppo :(
Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

Re: Nuova piccola applicazione

Messaggioda targzeta » lun giu 14, 2010 17:46

  • Codice: Seleziona tutto
    while(fgets(buffer,buff_size,fp)
    potrebbe non leggerti tutta la riga.
  • Codice: Seleziona tutto
    if ((cmd = realloc(cmd, buff_size *= 2)) == NULL)
    in pratica raddoppi la dimensione del buffer senza criterio ad ogni ciclo. Con dieci comandi da ignorare il tuo buffer passa da 2^7 a 2^17 byte, sei un bello sprecone.
  • Codice: Seleziona tutto
    strncat(cmd,buffer,strlen(buffer)-1);
    come ti ho detto il buffer potrebbe non contenere tutta la riga (basta che sia più grande di 128 caratteri. Anche se nel tuo caso può andar bene è comunque un errore, pensa se uno modifica il codice mettendoci una dimensione più piccola del buffer all'inizio, si trova un programma che non funziona e non sa perchè). Inoltre se alla fine non ci metti il terminatore di stringa ('/0') questo programma andrà comunque in segfault prima o poi.
Altri errori li hai già notati da solo, il memory leak va evitato (anche io non ho liberato la memoria) ma comunque quando il processo muore la memoria allocata viene liberata ugualmente.

Io il mio consiglio te l'ho dato ma da quello che ho capito sei uno a cui piace provare e riprovare invece che spendere meglio il suo tempo imparando una volta per tutte. L'approccio secondo me è sbagliato, ma buona fortuna.

Emanuele

P.S. Come ti ho gia detto per questo esercizio basta un solo buffer, non è obbligatorio ma finché ne usi due gli errori di distrazione possono capitare.
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6176
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: Nuova piccola applicazione

Messaggioda j0kers » lun giu 14, 2010 18:07

Uno legge e prova.Leggere soltanto senza provare non serve a nulla :D
Avatar utente
j0kers
Linux 2.4
Linux 2.4
 
Messaggi: 418
Iscritto il: dom lug 22, 2007 0:31
Slackware: 13
Kernel: 2.6.32
Desktop: xfce4

PrecedenteProssimo

Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite