aboutsummaryrefslogtreecommitdiffstats
path: root/csci1913/Java/project3/Words.java
blob: 04872670306efa9828f93b6a0800a8c9ccf4b8fe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package project3;
//
//  WORDS. An iterator that reads lower case words from a text file.
//
//    James Moen
//    19 Apr 17
//

import java.io.FileReader; //  Read Unicode chars from a file.
import java.io.IOException; //  In case there's IO trouble.

//  WORDS. Iterator. Read words, represented as STRINGs, from a text file. Each
//  word is the longest possible contiguous series of alphabetic ASCII CHARs.

class Words {
    private int ch; // Last CHAR from READER, as an INT.
    private FileReader reader; // Read CHARs from here.
    private StringBuilder word; // Last word read from READER.

    // Constructor. Initialize an instance of WORDS, so it reads words from a file
    // whose pathname is PATH. Throw an exception if we can't open PATH.

    public Words(String path) {
        try {
            reader = new FileReader(path);
            ch = reader.read();
        } catch (IOException ignore) {
            throw new IllegalArgumentException("Cannot open '" + path + "'.");
        }
    }

    // HAS NEXT. Try to read a WORD from READER, converting it to lower case as we
    // go. Test if we were successful.

    public boolean hasNext() {
        word = new StringBuilder();
        while (ch > 0 && !isAlphabetic((char) ch)) {
            read();
        }
        while (ch > 0 && isAlphabetic((char) ch)) {
            word.append(toLower((char) ch));
            read();
        }
        return word.length() > 0;
    }

    // IS ALPHABETIC. Test if CH is an ASCII letter.

    private boolean isAlphabetic(char ch) {
        return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z';
    }

    // NEXT. If HAS NEXT is true, then return a WORD read from READER as a STRING.
    // Otherwise, return an undefined STRING.

    public String next() {
        return word.toString();
    }

    // READ. Read the next CHAR from READER. Set CH to the CHAR, represented as an
    // INT. If there are no more CHARs to be read from READER, then set CH to -1.

    private void read() {
        try {
            ch = reader.read();
        } catch (IOException ignore) {
            ch = -1;
        }
    }

    // TO LOWER. Return the lower case ASCII letter which corresponds to the ASCII
    // letter CH.

    private char toLower(char ch) {
        if ('a' <= ch && ch <= 'z') {
            return ch;
        } else {
            return (char) (ch - 'A' + 'a');
        }
    }
    // MAIN. For testing. Open a text file whose pathname is the 0th argument from
    // the command line. Read words from the file, and print them one per line.

    public static void main(String[] args) {
        Words words = new Words(args[0]);
        while (words.hasNext()) {
            System.out.println("'" + words.next() + "'");
        }
    }
}