Nuova piccola applicazione
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.
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.
- Blallo
- Packager
- Messaggi: 3302
- Iscritto il: ven 12 ott 2007, 11:37
- Nome Cognome: Savino Liguori
- Slackware: 14.2 / 12.2
- Kernel: 4.4.14-smp
- Desktop: DWM
- Località: Torino / Torremaggiore (FG)
- Contatta:
Re: Nuova piccola applicazione
la soluzione che ti ha dato spina è un esempio
semplicemente al posto dei char "statici" puoi dargli in pasto un file di testo, semplicemente
semplicemente al posto dei char "statici" puoi dargli in pasto un file di testo, semplicemente
Github: https://github.com/8lall0
- j0kers
- Linux 2.x
- Messaggi: 418
- Iscritto il: dom 22 lug 2007, 1:31
- Slackware: 13
- Kernel: 2.6.32
- Desktop: xfce4
Re: Nuova piccola applicazione
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
comunque ci sono milioni di soluzioni per giungere alla medesima soluzione.
Dipende poi dal programmatore
- Blallo
- Packager
- Messaggi: 3302
- Iscritto il: ven 12 ott 2007, 11:37
- Nome Cognome: Savino Liguori
- Slackware: 14.2 / 12.2
- Kernel: 4.4.14-smp
- Desktop: DWM
- Località: Torino / Torremaggiore (FG)
- Contatta:
Re: Nuova piccola applicazione
e allora?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
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"
Github: https://github.com/8lall0
-
- Iper Master
- Messaggi: 3174
- Iscritto il: lun 3 set 2007, 21:20
- Nome Cognome: Mario Vanoni
- Slackware: 12.2
- Kernel: 3.0.4 statico
- Desktop: fluxbox/seamonkey
- Località: Cuasso al Monte (VA)
Re: Nuova piccola applicazione
Ancora piu` short:j0kers ha scritto:OppureGiusto ?Codice: Seleziona tutto
if( (fp=fopen("proc","r"))==NULL) exit(fprintf(stderr, "Errore apertura file!\n"));
Codice: Seleziona tutto
if(! (fp = fopen("proc","r")))
exit(fprintf(stderr, "Errore apertura file!\n"));
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!
- targzeta
- Iper Master
- Messaggi: 6629
- Iscritto il: gio 3 nov 2005, 14:05
- Nome Cognome: Emanuele Tomasi
- Slackware: 64-current
- Kernel: latest stable
- Desktop: IceWM
- Località: Carpignano Sal. (LE) <-> Pisa
Re: Nuova piccola applicazione
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):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!
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:
...
Emanuele
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
- gallows
- Staff
- Messaggi: 3470
- Iscritto il: lun 20 set 2004, 0:00
- Slackware: 64-current
- Kernel: 5.10.7
- Località: ~/
- Contatta:
Re: Nuova piccola applicazione
Programs should be written for people to read, and only incidentally for machines to execute.Mario Vanoni ha scritto:Ancora piu` short:j0kers ha scritto:OppureGiusto ?Codice: Seleziona tutto
if( (fp=fopen("proc","r"))==NULL) exit(fprintf(stderr, "Errore apertura file!\n"));
Codice: Seleziona tutto
if(! (fp = fopen("proc","r"))) exit(fprintf(stderr, "Errore apertura file!\n"));
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
- masalapianta
- Iper Master
- Messaggi: 2775
- Iscritto il: lun 25 lug 2005, 0:00
- Nome Cognome: famoso porco
- Kernel: uname -r
- Desktop: awesome
- Distribuzione: Debian
- Località: Roma
- Contatta:
Re: Nuova piccola applicazione
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.
-
- Linux 3.x
- Messaggi: 760
- Iscritto il: gio 7 ago 2008, 12:29
- Slackware: slackware64-current
- Kernel: 3.4.4-ck3
- Desktop: FluxBox-1.3.1
- Distribuzione: FreeBSD-8.1(amd64)
- Località: London
Re: Nuova piccola applicazione
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.masalapianta ha scritto:
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.
- j0kers
- Linux 2.x
- Messaggi: 418
- Iscritto il: dom 22 lug 2007, 1:31
- Slackware: 13
- Kernel: 2.6.32
- Desktop: xfce4
Re: Nuova piccola applicazione
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;
}
-
- Linux 3.x
- Messaggi: 760
- Iscritto il: gio 7 ago 2008, 12:29
- Slackware: slackware64-current
- Kernel: 3.4.4-ck3
- Desktop: FluxBox-1.3.1
- Distribuzione: FreeBSD-8.1(amd64)
- Località: London
Re: Nuova piccola applicazione
Io direi poi di liberare il puntatore.
- j0kers
- Linux 2.x
- Messaggi: 418
- Iscritto il: dom 22 lug 2007, 1:31
- Slackware: 13
- Kernel: 2.6.32
- Desktop: xfce4
Re: Nuova piccola applicazione
Mi sono dimenticato anche di chiudere il file Errori di svista purtroppo
- targzeta
- Iper Master
- Messaggi: 6629
- Iscritto il: gio 3 nov 2005, 14:05
- Nome Cognome: Emanuele Tomasi
- Slackware: 64-current
- Kernel: latest stable
- Desktop: IceWM
- Località: Carpignano Sal. (LE) <-> Pisa
Re: Nuova piccola applicazione
- potrebbe non leggerti tutta la riga.
Codice: Seleziona tutto
while(fgets(buffer,buff_size,fp)
- 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
if ((cmd = realloc(cmd, buff_size *= 2)) == NULL)
- 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.
Codice: Seleziona tutto
strncat(cmd,buffer,strlen(buffer)-1);
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.
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
- j0kers
- Linux 2.x
- Messaggi: 418
- Iscritto il: dom 22 lug 2007, 1:31
- Slackware: 13
- Kernel: 2.6.32
- Desktop: xfce4
Re: Nuova piccola applicazione
Uno legge e prova.Leggere soltanto senza provare non serve a nulla