Newsgroup: it.comp.lang.c
Titolo: Riconoscimento OS

Ciao a tutti
C'č un modo per ottenere il nome del sistema operativo? Di modo che se č
linux faccio una system ("clear") se č windows faccio una system("cls").
Altrimenti ditemi se lo sapete un metodo piů semplice per cancellare lo
schermo. Cio che mi importa č che vda bene su qualsiasi OS.
Ciao
    Bedo
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 schermo. Cio che mi importa č che vda bene su qualsiasi OS.
int a = 25;
while (a--) printf ("\n"); 

 schermo. Cio che mi importa è che vda bene su qualsiasi OS.
Allora non c'è - più semplice, intendo. Se non vuoi chiamare le funzioni
built-in di una shell, devi andare a recuperare librerie di gestione del
terminale.
Ciao,
 Emmanuele.
-- 
Emmanuele Bassi (Zefram)                 [ 
http://www.emmanuelebassi.net
 ]
GnuPG Key fingerprint = 4DD0 C90D 4070 F071 5738  08BD 8ECC DB8F A432 0FF4

 while (a--) printf ("\n"); 
E se io usassi un terminale da 110x37 (come questo) o, peggio, 128x47
(come la mia console)? ;-)



E se ho piu' di 25 colonne?? :)
-- 
Mat/tia Belletti - Graduate student @ 
cs.unibo.it
ICQ: 33292311    - email: 
mbel...@cs.unibo.it
IRC: RedGlow     - site(s): 
http://mbellett.web.cs.unibo.it/
Jabber: RedGlow  - Linux registered user 299762 @ machine 213003

 while (a--) printf ("\n"); 
kronos:~$ stty -a
speed 38400 baud; rows 48; columns 128; line = 0;
:P
Tornando all'OP, un metodo sicuro al 100% non c'e`, dovresti isolare
tutto il codice non portabile in una libreria e scrivere diverse
versioni per ogni OS. La libreria giusta viene linkata quando il
programma viene compilato.
Oppure puoi usare una libreria di gestione del terminale portabile
(tipo le ncurses).
Luca
-- 
Home: 
http://kronoz.cjb.net
Windows NT crashed.
I'm the Blue Screen of Death.
No one hears your screams.

 E se ho piu' di 25 colonne?? :)
Di solito i terminali hanno 25 colonne, se ne hai di più ti regoli di 
conseguenza o con delle #define opportunamente incluse nel preprocessore 
oppure durante il run time con delle semplici variabili.
IMHO in C standard non esiste un metodo per capire il terminale quante righe 
ha o meglio il metodo ci sarebbe ma la mia soluzione è un pò macchinosa ;-)

 E se ho piu' di 25 colonne?? :)
facciamo righe :)

 C'č un modo per ottenere il nome del sistema operativo? 
Si e no. Sono definite di solito delle costanti simboliche che indicano 
l'ambiente in cui stai compilando, ma non esiste uno "standard" per 
questo. Quindi niente vieta che tu lo faccia nei tuoi makefile o nei 
tuoi ide.

  Emmanuele.
int a = 1000; /* per andare sul sicuro... -_^ */
while (a--) printf ("\n");
Se la scelta e' solo tra linux e windows, non e' possibile in qualche modo,
all'inizio del programma, 'provare' ad eseguirle entrambe e scegliere quella
che non da' qualche tipo di errore?
Boh!
Ciao,
Ema


ok, facciamo righe, ma giusto perche' sei tu... ;D


 che non da' qualche tipo di errore?
Si` puo` controllare il valore di ritorno della system ed agire di
conseguenza. Nulla vieta, pero`, che si sia un esegubile chiamato 'cls'
su una certa macchina linux oppure uno chiamato 'clear' sotto win.
Si potrebbe provare ad aprire (ad esempio) /proc/version, se il file non
esiste l'OS non e` linux (oppure /proc non e` montata :|).
Luca
-- 
Home: 
http://kronoz.cjb.net
Ci sono due cose che l'uomo non puo` nascondere:
essere ubriaco ed essere innamorato.

 che e` la sequenza di cancellazione.
Solo se carichi ANSI.SYS quindi dar risultato non garantito.
-- 
-=[]=---iAN CooG/HokutoForce+TWT---=[]=-
http://iancoog.altervista.org/

 che non da' qualche tipo di errore?
Controlli il valore di ritorno di system("..."), ma la shell ti
insulterà visibilmente, se non trova "clear" o "cls".


 
Avevo aggiunto anche che occorre identificare il terminale.  Non tutti 
riconoscono le sequenze ANSI per per gestire lo schermo.
ANSI.SYS si riferisce solo al M$-DOS (e suoi derivati).
Un programma dovrebbe (e 'clear' fa questo):
    -	identificare il terminale
    -	aprire il database dei terminali
    -	identificate il gruppo di 'capabilities' relative al terminale
    -	emettere la sequenza relativa alla capability "cl"
Naturalmente su ambiente MS tutto cio` non esiste.


 esiste l'OS non e` linux (oppure /proc non e` montata :|).
Trovare una Linux box senza /proc penso sia complicato, di questi giorni.
:-)
A questo punto, non credo che, *a run-time*, un controllo del genere sia
fattibile, o perlomeno con una percentuale di falsi negativi accettabile.


 #endif /* IS_UNIX */
Una domanda, come mai quel do while(0)? Sembrerebbe inutile?
Non sarebbe andato bene scrivere:
#define    DO_CLEAR_TERMINAL    system("clear");


Senza il punto e virgola, ma in effetti si', e' meglio.
Il 'trucco' del while(0) serve solo in caso di piu' istruzioni.


 #define    DO_CLEAR_TERMINAL    system("clear");
Senza il punto e virgola, altrimenti violi la semantica degli statement
in C.


 in C.
Bisognerebbe fare:
#define    DO_CLEAR_TERMINAL    system("clear")
in modo che durante il codice io metta:
code...
DO_CLEAR_TERMINAL;
code...
pero` la cosa non mi fa impazzire a livello "estetico" - se io guardo il
codice e vedo 'DO_CLEAR_TERMINAL;' non capisco se e` una funzione un
assegnazione o... devo starmene del nome!?!
Un ultima cosa:
cosa vuol dire "violi la semantica degli statement in C"
se si faceva come dicevo prima, vorra` dire che se uno aggiunge il ; ci
sara` uno statement vuoto?!? Non lo farei, ma e` giusto per capire...

 sara` uno statement vuoto?!? Non lo farei, ma e` giusto per capire...
AHH, cavolo, mi rispondo da solo
ad es. ci sarebbero dei problemi nel flusso if else...

 assegnazione o... devo starmene del nome!?!
Puoi sempre fare:
#define DO_CLEAR_TERMINAL() system("clear")
...
DO_CLEAR_TERMINAL();
...
Non che sia molto piu` bello, anche perche` _sembra_ una funzione ma non
lo e`. In ogni caso il fatto che sia tutta uppercase e` forte
indicatore che la riga in questione non e` un normale statement
(funzione); questa convenzione non scritta si usa proprio per distiguere
subito le macro.
Luca
-- 
Home: 
http://kronoz.cjb.net
La mia opinione puo` essere cambiata, ma non il fatto che ho ragione.

 sara` uno statement vuoto?!? Non lo farei, ma e` giusto per capire...
E` solo una questione estetica ed a volte di strumenti di analisi del 
codice che si arrabbiano se non trovano ; alla fine dello statement.
Ad ogni modo in genere non succede niente se il compilatore trova 
statement vuoti (solo ;).


 subito le macro.
eh gia`...
Ciao

 statement vuoti (solo ;).
Pero`, come mi sono risposto da solo prima, mi sembra che mettendolo gia`
nella macro puo` essere pericoloso, ad es.:
#define    DO_CLEAR_TERMINAL()    system("clear");
(1)
if( 1 )
    DO_CLEAR_TERMINAL();
else
    ...
(2)
if( ! DO_CLEAR_TERMINAL() )
    ...
else
    ...
in questi 2 casi si commette errore...

 una curiosita`, perche` le parentesi nei parametri (a) e (b)
Nel caso specifico sono superflue ma e` sempre buona abitudine metterle
per forzare la precedenza di quello che e` stato passato come parametro.
Ad esempio:
#define TRIPLE(a) (a * 3)
e` scorretto perche` puo` causare dei problemi con le precedenze degli
operatori. Ad esempio:
z = TRIPLE(x + y);
viene espanso in:
z = (x + y * 3);
che non fa quello che uno si aspetterebbe. Questo avviene perche` con le
macro non c'e` un vero e proprio passaggio degli argomenti (con una
funzione x + y verrebbe valutato prima dell'invocazione della funzione
stessa). Forzando la precedenza con le parentesi:
#define TRIPLE(a) ((a) * 3)
si avrebbe:
z = ((x + y) * 3);
Come nota personale aggiungo che io preferisco usare le funzioni inline
(C99) al posto delle simil-funzioni fatte con le macro, visto che si
ottiene un risultato a livello di assembly praticamente identico ed in
piu` si ha la semantica di una vera e propria funzione.
La macro le uso praticamente solo per le costanti simboliche.
Luca
-- 
Home: 
http://kronoz.cjb.net
Mi piace avere amici rispettabili;
Mi piace essere il peggiore della compagnia.

 in questi 2 casi si commette errore...
Giusto! per questa ragione e` sempre consigliabile mettere
{ } nei blocchi dopo if(...) ed else.  Anche se lo statement e` uno solo.


 { } nei blocchi dopo if(...) ed else.  Anche se lo statement e` uno solo.
Direi piuttosto che e` bene usare dei trucchi come do {} while(0) per le
macro.
if (quux)
        foo();
else
        bar();
E` perfettamente leggibile, le parentesi non aggiugono nulla. Se le
parentesi aggiunte servono solo per proteggersi da macro strane allora (IMHO)
si sta semplicemente mascherando un bug al posto di correggerlo.
Altrimenti de gustibus non disputandum est.
Luca
-- 
Home: 
http://kronoz.cjb.net
Un apostolo vedendo Gesu` camminare sulle acque:
- Cazzo se e` buono 'sto fumo!!!