001package fi.jyu.mit.ohj2;
002import java.io.*;
003
004/**
005 * <p>Title: Syotto</p>
006 * <p>Description: Aliohjelmia tietojen lukemiseen päätteeltä</p>
007 * <p>Lukeminen on vaihdettu käyttämään omaa RiviLukijaa jotta
008 * syötön uudelleensuuntaus toimisi paremmin</p>
009 * <p>Copyright: Copyright (c) 2003</p>
010 * <p>Company: jyu </p>
011 * @author Vesa Lappalainen
012 * @version 1.0/08.01.2003
013 * @version 1.1/25.01.2003
014 * @version 1.2/11.03.2007
015 */
016
017public class Syotto {
018
019  /**
020   * Lukija joka lukee yden rivin InputStreamista
021   * @author vesal
022   * @version 11.3.2007
023   */
024  public static class RiviLukija {
025    /**
026     * Jos edellinen merkki on CR, niin seuraava LF unohdetaan
027     */
028    //private boolean lastCR = false;
029    //private InputStream in;
030    private final BufferedReader inb; 
031    
032    /**
033     * Alustetaan lukija lukemaan tiettyä tietovirtaa
034     * @param in tietovirta jota luetaan
035     */
036    public RiviLukija(InputStream in) {
037      //this.in = in;
038      inb = new BufferedReader(new InputStreamReader(in));
039    }
040    
041    /**
042     * Luetaan rivi tietovirrasta. rivinvaihtona kelpaa
043     * cr, lf  tai crlf
044     * @return luettu rivi tai null jos tietovirta "loppu"
045     */
046    public String lueRivi() {
047    /*  
048      StringBuffer sb = new StringBuffer();
049      int n = 0;
050      while ( true ) {
051        int c;
052        try {
053          c = in.read();
054          if ( c < 0 ) if ( n == 0 ) return null; else break;
055          n++;
056          if ( c == '\r' ) { lastCR=true; break; }
057          if ( c == '\n' ) if ( lastCR ) { lastCR = false; continue; } else break;
058          lastCR = false;
059        } catch (IOException e) {
060          break;
061        }
062        sb.append((char)c);
063      }
064      return sb.toString();
065    */  
066      
067      try {
068        return inb.readLine();
069      } catch (IOException e) {
070        return "";
071      }
072    }
073    
074  }
075  
076  /**
077   * Tietovirran lukija
078   */
079  private static RiviLukija lukija = new RiviLukija(System.in);
080
081  /**
082   * Alustaa sisäisen lukijan uudelleen mahdollisen suuntauksen jälkeen.
083   *
084   */
085  public static void alusta() {
086      lukija = new RiviLukija(System.in);    
087  }
088  
089  
090  /**
091   * Luetaan seuraava rivi System.in-tieotovirrasta
092   * @return luettu rivi
093   */
094  public static String lueRivi() {
095    return lukija.lueRivi();
096  }
097  
098  
099  /**
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}