abenobashi
06-09-2011, 12:43
Qualcouno sa dirmi dove posso trovare una lista dei comandi di java con il "\". Ad esempio \n serve per andare a capo. Però a me servirebbe quello per andare ad inizio riga
Qualcouno sa dirmi dove posso trovare una lista dei comandi di java con il "\". Ad esempio \n serve per andare a capo. Però a me servirebbe quello per andare ad inizio riga
carriage return \r
le altre http://download.oracle.com/javase/tutorial/java/data/characters.html
per la cronaca si chiamano sequenze di escape ( Escape Sequences )
banryu79
06-09-2011, 13:03
Ciao, "\n" è la sequenza di escape che nella codifica ASCII corrisponde al caratter di controllo "Line Feed".
Il carattere '\', all'interno di una stringa letterale, è un metacarattere che serve a introdurre una sequenza di escape.
Eccoti un link a una tabella ASCII (http://it.wikipedia.org/wiki/ASCII): i primi 32 sono i "caratteri di conrtollo", cioè caratteri non stampabili che includono vari "comandi": solo per alcuni di questi sono presenti anche le relative sequenze di escape (nella tabella, sotto la colonna "CEC").
abenobashi
06-09-2011, 18:54
Grazie mille per le risposte ho provato ad usare il carriage return (\r) ma sembra non funzionarmi. Perchè ho provato a stampare una cosa che viene stampata ogni tot di secondi e poi volevo far in modo che venisse sovrascritto quello che è stato scritto precedentemente. Se serve ecco il codice che è piuttosto semplice:
public class StellaAnimata {
public static void main(String[] args) throws InterruptedException {
int stato = 0;
while (true)
{
if(stato == 0 || stato == 4)
{
System.out.print("| \r");
if(stato == 4)
{
stato = 1;
}
else
{
stato += 1;
}
Thread.sleep(100);
}
if(stato == 1)
{
System.out.print("\\ \r");
stato += 1;
Thread.sleep(100);
}
if(stato == 2)
{
System.out.print("- \r");
stato += 1;
Thread.sleep(100);
}
if(stato == 3)
{
System.out.print("/ \r");
stato += 1;
Thread.sleep(100);
}
}
}
}
Facendo così quando sta partendo il programma non si vede nulla ma una volta stoppato si vedo tutti i trattini stampati uno dopo l'altro. Mentre se faccio stampare a capo si vede anche mentre va il programma. Però vorrei che venisse sovrascritto sulla stessa riga se possibile ma con "\r" non mi funziona.
banryu79
07-09-2011, 13:19
Ciao, cerco di essere esaustivo, allora:
Grazie mille per le risposte ho provato ad usare il carriage return (\r) ma sembra non funzionarmi.
il carattere di controllo "Carriage Return" non cancella nulla, concettualmente posiziona il cursore a inizio linea.
Ci sono alcuni caratteri di controllo ASCII associati al concetto del "cancellare" qualcosa che è stato scritto, ad esempio "Backspace" oppure "Delete" (vedi la tabella precedentemente linkata).
Ma anche con questi caratteri di controllo, da codice Java, non ci fai molto.
Immagino che il tuo sia una sorta di esercizio, e che tu stia imparando a programmare. Un conto quindi è lo scopo del programma in sè stesso (ottenere un preciso risultato: un rudimentale effetto di animazione usando dei caratteri ascii stampati sulla consolle) e un conto è lo scopo dello scrivere quel programma (esercitarsi, scrivere codice sintatticamente e semanticamente corretto, imparare cose nuove, ecc...).
Per quanto riguarda "lo scopo dello scrivere quel programma (esercitarsi)", forse non ti sei accorto che puoi semplificare la struttura del tuo codice eliminando le "cose inutili". Ad esempio: hai definito 5 stati, da 0 a 4; per passare da uno stato al successivo incrementi il valore dello stato di uno e siccome l'ultimo stato utile è quello che vale 3, e viene quindi poi incrementato a 4, hai mappato il valore 1 e 4 per il primo stato.
Il tuo sistema è correto da un punto di vista logico, ma non era meno confusionario mappare i valori 1, 2, 3, 4 con i rispettivi stati per poi passare da uno all'altro semplicemente assegnando allo stato il valore desiderato? Il tuo ciclo while diventerebbe così:
while (true) {
if (stato == 1) {
System.out.print("| \r");
stato = 2
Thread.sleep(100);
}
if (stato == 2) {
System.out.print("\\ \r");
stato = 3;
Thread.sleep(100);
}
if (stato == 3) {
System.out.print("- \r");
stato = 4;
Thread.sleep(100);
}
if (stato == 4) {
System.out.print("/ \r");
stato = 1;
Thread.sleep(100);
}
}
Fatta questa "semplificazione" ed esaminando il nuovo codice è evidente che se ne può fare un'altra: eliminare gli if e accodare in sequenza tutte le operazioni, dato che ad ogni iterazione del cilco while è chiaro che vengono eseguiti tutti gli if!
E quindi il while si riduce a:
while (true) {
System.out.print("| \r");
Thread.sleep(100);
System.out.print("\\ \r");
Thread.sleep(100);
System.out.print("- \r");
Thread.sleep(100);
System.out.print("/ \r");
Thread.sleep(100);
}
A questo punto diventa evidente che il ciclo while non fa altro che ripetere sequenzialmente, per quattro volte, la stessa "istruzione logica": stampare qualcosa sullo standard output e sospendere l'esecuzione del thread per fare una piccola pausa.
Esaminando meglio, si può notare che ciò che ogni volta cambia in questa sorta di "istruzione logica" è solo ciò che viene stampato.
A questo punto si può sintetizzare questa "istruzione logica" con un metodo: gli si da un nome e lo si definisce con un argomento in ingresso (una String), ad esempio:
private static void printAndWait(String string) {
System.out.print(string);
Thread.sleep(100);
}
ecco che abbiamo semplificato e sintetizzato il codice iniziale:
public class StellaAnimata
{
public static void main(String[] args) throws InterruptedException {
while (true) {
printAndWait("| \r");
printAndWait("\\ \r");
printAndWait("- \r");
printAndWait("/ \r");
}
}
private static void printAndWait(String string) {
System.out.print(string);
Thread.sleep(100);
}
}
Il codice qui sopra è semanticamente equivalente a quello da te postato: se lo mandi in esecuzione l'output prodotto è uguale.
-----
Per quanto riguarda invece "lo scopo del programma in sè stesso (ottenere l'animazione ascii)" ti dico che non lo puoi ottenere nel modo in cui pensi; ovvero non c'e' un modo, tramite System.out, di "sovvrascrivere" quello che vedi in consolle.
Questo perchè le stringhe che stampi con i comandi "print" in System.out, vengono per prima cosa accodate in uno stream che funge da buffer di accumulazione interno a System stesso (quell'out si System.out è uno PrintWriter, cioè lo stream su cui si può stampare).
Ogni volta che stampi delle stringhe, non fai altro che accodarle in out (il PrintWriter). Se le accodi con i metodi "print", lo stream non viene "flushato" (leggi: scaricato) immediatamente sulla destinazione (la consolle), invece con "println" (e non mi ricordo più che altri metodi) memorizzi la stringa passata e forzi un "flush" del contenuto dello stream sulla destinazione alla quale è collegato (uno stream collega una sorgente con una destinazione).
Esiste un apposito metodo per forzare lo scaricamento dello stream: flush.
Lo usiamo così, ad esempio:
...
private static void printAndWait(String string) {
System.out.print(string);
System.out.flush();
Thread.sleep(100);
}
...
I primi 32 caratteri ascii sono dei caratteri "di controllo": erano cioè pensati per controllare i device su cui si stampava (pensa al new line e al carriage return, che concettualmente mimano rispettivamente l'andare giù di una linea e il ritornare a capo col carrello nelle macchina da scrivere e in non so quali vecchi device di stampa) e non per stampare effettivamente qualcosa.
E' per questo che se stampi su System.out caratteri di controllo come ad esempio \b (Basckspace) non ottieni ciò che ti aspetteresti: se ci pensi non puoi cancellare i dati già inviati sullo stream, perchè magari nel frattempo lo stream è stato svuotato. Quello che vorresti cancellare è già stato stampato sullo stream di output collegato, la consolle.
Servirebbe quindi un comando per dire alla consolle: cancella, fai backspace.
Ma la "consolle" non è un componente Java: la consolle viene messa a disposizione dal sistema operativo specifico e quindi per fare quello che vuoi tu bisogna percorrere altre strade, che esulano dal contesto Java puro e semplice e c'entrano poco con la tua esercitazione.
Posso farti due esempi con cui riesco a ottenere l'effetto di animazione sul mio pc. Io uso un IDE per programmare in Java, che si chiama NetBeans. Posso lanciare i miei programmi direttamente da NetBeans e se il programma gira in consolle, NetBeans stampa l'output sulla sua implementazione interna di consolle e non su la consolle del sistema operativo.
Questo programma esegue l'effeto di animazione se lanciato dall'IDE NetBeans (e se la finestra di consolle è dimensionata a 16 righe di altezza):
public class StellaAnimata
{
public static void main(String[] args) {
while (true) {
printAndWait("|");
printAndWait("\\");
printAndWait("-");
printAndWait("/");
}
}
private static void printAndWait(String string) {
// uso 15 newline perche' sto lanciando il programma
// dall'IDE NetBeans e attualmente l'altezza della
// consolle di output integrata e' tale da mostrare
// 16 linee (quindi ne stampo 15 vuote e sulla 16esima
// stampo il carattere.
System.out.print("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
System.out.print(string);
System.out.flush();
try {
Thread.sleep(250);
} catch (InterruptedException ignored) {};
}
}
Per ottenere lo stesso effetto in una consolle su Windows (io sono su WinXP)
si può sfruttare il comando "CLS" (clear screen) e qualche barbatrucco particolare per ottere un dalay di esecuzione dei comandi specificati in un file .bat da mandare in esecuzione.
Dopo qualche prova ho trovato che 'sta roba da me funziona:
@echo off
REM create a wb script used to sleep for some time
REM each time it is invoked (calling to WScript.Sleep)
> "%Temp%.\sleep.vbs" echo WScript.Sleep 50
REM counter used to exit the loop
setlocal
set /a max=10
set /a counter=0
:START
if %counter%==%max% goto :END
cls
echo ^|
cscript //NoLogo "%Temp%.\sleep.vbs"
cls
echo ^/
cscript //NoLogo "%Temp%.\sleep.vbs"
cls
echo ^-
cscript //NoLogo "%Temp%.\sleep.vbs"
cls
echo ^\
cscript //NoLogo "%Temp%.\sleep.vbs"
set /a counter=%counter%+1
goto :START
endlocal
:END
cls
del "%Temp%.\sleep.vbs"
Entrambe le soluzioni funzionano ma, ovviamente, entrambe sono uno schifo: do this at home but don't take it seriously!
Spero di averti chiarito qualche dubbio :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.