1   package fi.jyu.mit.ohj2;
2   import java.io.*;
3   
4   /**
5    * <p>Title: Syotto</p>
6    * <p>Description: Aliohjelmia tietojen lukemiseen päätteeltä</p>
7    * <p>Lukeminen on vaihdettu käyttämään omaa RiviLukijaa jotta
8    * syötön uudelleensuuntaus toimisi paremmin</p>
9    * <p>Copyright: Copyright (c) 2003</p>
10   * <p>Company: jyu </p>
11   * @author Vesa Lappalainen
12   * @version 1.0/08.01.2003
13   * @version 1.1/25.01.2003
14   * @version 1.2/11.03.2007
15   */
16  
17  public class Syotto {
18  
19    /**
20     * Lukija joka lukee yden rivin InputStreamista
21     * @author vesal
22     * @version 11.3.2007
23     */
24    public static class RiviLukija {
25      /**
26       * Jos edellinen merkki on CR, niin seuraava LF unohdetaan
27       */
28      //private boolean lastCR = false;
29      //private InputStream in;
30      private final BufferedReader inb; 
31      
32      /**
33       * Alustetaan lukija lukemaan tiettyä tietovirtaa
34       * @param in tietovirta jota luetaan
35       */
36      public RiviLukija(InputStream in) {
37        //this.in = in;
38        inb = new BufferedReader(new InputStreamReader(in));
39      }
40      
41      /**
42       * Luetaan rivi tietovirrasta. rivinvaihtona kelpaa
43       * cr, lf  tai crlf
44       * @return luettu rivi tai null jos tietovirta "loppu"
45       */
46      public String lueRivi() {
47      /*  
48        StringBuffer sb = new StringBuffer();
49        int n = 0;
50        while ( true ) {
51          int c;
52          try {
53            c = in.read();
54            if ( c < 0 ) if ( n == 0 ) return null; else break;
55            n++;
56            if ( c == '\r' ) { lastCR=true; break; }
57            if ( c == '\n' ) if ( lastCR ) { lastCR = false; continue; } else break;
58            lastCR = false;
59          } catch (IOException e) {
60            break;
61          }
62          sb.append((char)c);
63        }
64        return sb.toString();
65      */  
66        
67        try {
68          return inb.readLine();
69        } catch (IOException e) {
70          return "";
71        }
72      }
73      
74    }
75    
76    /**
77     * Tietovirran lukija
78     */
79    private static RiviLukija lukija = new RiviLukija(System.in);
80  
81    /**
82     * Alustaa sisäisen lukijan uudelleen mahdollisen suuntauksen jälkeen.
83     *
84     */
85    public static void alusta() {
86        lukija = new RiviLukija(System.in);    
87    }
88    
89    
90    /**
91     * Luetaan seuraava rivi System.in-tieotovirrasta
92     * @return luettu rivi
93     */
94    public static String lueRivi() {
95      return lukija.lueRivi();
96    }
97    
98    
99    /**
100    * Aliohjelmalla kysytään käyttäjältä arvo merkkijonolle.
101    * Jos tulOletus on tosi, tulostetaan oletusarvo.
102    * Jos käyttäjä painaa pelkästään ret, palautetaan oletusarvo
103    *
104    * @param kysymys käyttäjälle tulostettava kysymys
105    * @param oletus arvo jota käytetään jos painetaan pelkkä ret
106    * @param tulOletus tulostetaanko oletus käyttäjälle
107    * @return käyttäjän syöttämä merkkijono
108    */
109   public static String kysy(String kysymys, String oletus, boolean tulOletus) {
110     //BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
111     while ( true ) {
112       System.out.print(kysymys);
113       if ( tulOletus ) System.out.print(" (" + oletus + ")");
114       System.out.print(" >");
115       String s = "";
116       //try {
117         //s = in.readLine();
118         s = lueRivi();
119       //} catch (IOException ex) {
120       //  continue;
121       //}
122       if ( ( s == null ) || ( s.equals("") ) ) return oletus;
123       return s;
124     }
125 
126   }
127 
128   /**
129    * Aliohjelmalla kysytään käyttäjältä arvo merkkijonolle.
130    * Tulostetaan oletusarvo.
131    * Jos käyttäjä painaa pelkästään ret, palautetaan oletusarvo
132    *
133    * @param kysymys käyttäjälle tulostettava kysymys
134    * @param oletus arvo jota käytetään jos painetaan pelkkä ret
135    * @return käyttäjän syöttämä merkkijono
136    */
137   public static String kysy(String kysymys, String oletus) {
138     return kysy(kysymys,oletus,true);
139   }
140 
141   /**
142    * Aliohjelmalla kysytään käyttäjältä arvo merkkijonolle.
143    * Ei tulosteta oletusarvoa.
144    *
145    * @param kysymys käyttäjälle tulostettava kysymys
146    * @return käyttäjän syöttämä merkkijono
147    */
148   public static String kysy(String kysymys) {
149     return kysy(kysymys,"",false);
150   }
151 
152   /**
153    * Kysytään reaaliluku. Jos annetaan ei-luku, kysytään uudelleen.
154    * @param kysymys näytölle tulostettava kysymys
155    * @param oletus arvo jota käytetään jos painetaanpelkkä Ret
156    * @param tulOletus tulostetaanko oletus käyttäjälle
157    * @return käyttäjän kirjoittama reaaliluku
158    */
159   public static double kysy(String kysymys, double oletus, boolean tulOletus) {
160     while ( true ) {
161       String s = kysy(kysymys,""+oletus,tulOletus);
162       s = s.trim();
163       if ( s.length() == 0 ) return oletus;
164       try {
165         return Double.parseDouble(s);
166       } catch (NumberFormatException ex) {
167         System.out.println("Ei numero: \"" + s + "\"");
168       }
169     }
170   }
171 
172   /**
173    * Kysytään reaaliluku. Jos annetaan ei-luku, kysytään uudelleen.
174    * Oletusarvo tulostetaan sulkuihin.
175    * @param kysymys näytölle tulostettava kysymys
176    * @param oletus arvo jota käytetään jos painetaanpelkkä Ret
177    * @return käyttäjän kirjoittama reaaliluku
178    */
179   public static double kysy(String kysymys, double oletus) {
180     return kysy(kysymys,oletus,true);
181   }
182 
183   /**
184    * Kysytään reaaliluku. Jos annetaan ei-luku, kysytään uudelleen.
185    * Ei tulosteta oletusta.
186    * @param kysymys näytölle tulostettava kysymys
187    * @return käyttäjän kirjoittama reaaliluku
188    */
189   public static double kysyDouble(String kysymys) {
190     return kysy(kysymys,0.0,false);
191   }
192 
193   /**
194    * Kysytään kokonaisluku. Jos annetaan ei-luku, kysytään uudelleen.
195    * @param kysymys näytölle tulostettava kysymys
196    * @param oletus arvo jota käytetään jos painetaanpelkkä Ret
197    * @param tulOletus tulostetaanko oletus käyttäjälle
198    * @return käyttäjän kirjoittama kokonaisluku
199    */
200   public static int kysy(String kysymys, int oletus, boolean tulOletus) {
201     while ( true ) {
202       String s = kysy(kysymys,""+oletus,tulOletus);
203       s = s.trim();
204       if ( s.length() == 0 ) return oletus;
205       try {
206         return Integer.parseInt(s);
207       } catch (NumberFormatException ex) {
208         System.out.println("Ei kokonaisluku: \"" + s + "\"");
209       }
210     }
211   }
212 
213   /**
214    * Kysytään kokonaisluku. Jos annetaan ei-luku, kysytään uudelleen.
215    * Oletusarvo tulostetaan sulkuihin.
216    * @param kysymys näytölle tulostettava kysymys
217    * @param oletus arvo jota käytetään jos painetaanpelkkä Ret
218    * @return käyttäjän kirjoittama kokonaisluku
219    */
220   public static int kysy(String kysymys, int oletus) {
221     return kysy(kysymys,oletus,true);
222   }
223 
224   /**
225    * Kysytään kokonaisluku. Jos annetaan ei-luku, kysytään uudelleen.
226    * Ei tulosteta oletusta.
227    * @param kysymys näytölle tulostettava kysymys
228    * @return käyttäjän kirjoittama kokonaisluku
229    */
230   public static int kysyInt(String kysymys) {
231     return kysy(kysymys,0,false);
232   }
233 
234 
235   
236   /**
237    * Testataan kysy-metodeja
238    * @param args ei käytössä
239    */
240   public static void main(String[] args) {
241     String s = kysy("Anna jono","Kissa");
242     System.out.println("Jono oli: \"" + s + "\"");
243     String s2 = kysy("Anna jono");
244     System.out.println("Jono oli: \"" + s2 + "\"");
245     double d = kysy("Anna reaaliluku",3.14);
246     System.out.println("Luku oli: \"" + d + "\"");
247     int i = kysyInt("Anna kokonaisluku");
248     System.out.println("Luku oli: \"" + i + "\"");
249     d = kysyDouble("Anna reaaliluku");
250     System.out.println("Luku oli: \"" + d + "\"");
251   }
252 }
253