-1

So far I have the following code below. Coding is a new hobby for me and I am below a beginner. I copied and pasted this from stackoverflow in order to read a text file

    BufferedReader r = new BufferedReader( new FileReader( "test.txt" ) );
    String s = "", line = null;
    while ((line = r.readLine()) != null) {
        s += line;
    }
     

and then this from a website I found to print one word at a time.

       int i;          // Position in line, from 0 to line.length() - 1.
       char ch;        // One of the characters in line.
       boolean didCR;  // Set to true if the previous output was a carriage return.
       
       
       System.out.println();
       didCR = true;
       
       for ( i = 0;  i < s.length();  i++ ) {
          ch = s.charAt(i);
          if ( Character.isLetter(ch) ) {
             System.out.print(ch);
             didCR = false;
          }
          else {
             if ( didCR == false ) {
                System.out.println();
                didCR = true;
             }
          }
          
       }
       
       System.out.println();  // Make sure there's at least one carriage return at the end.

I would really love to output the text file, one word at a time by whitespace so that characters such as commas and periods are included. Please help!

  • 3
    Welcome to SO. As a beginner you should definitely not only copy code but try to understand it. Have a look at the JavaDocs attached to each of the JDK classes to get some understanding of what the methods are doing. That said, the second code looks very complicated for just printing words one at a time. The first snippet to read a file line by line is ok, just don't add the line to a string but `split()` it at whitespace and use an inner loop to print each word on a new line (`System.out.println(word)`). – Thomas Jan 22 '21 at 07:41
  • If you want words-by-whitespace instead of words-by-nonletter, just replace [`Character.isLetter(ch)`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isLetter-char-) with [`! Character.isWhitespace(ch)`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#isWhitespace-char-). – Andreas Jan 22 '21 at 07:41
  • 1
    One note on the first snippet: `s += line;` might cause problems when trying to print individual words out of `s` later. Assume the the file looks like this: `line one\nline two`. Reading the file you would get `line one` and `line two` but just concatenating them would then result in `line oneline two` (note the missing whitespace after `one`). – Thomas Jan 22 '21 at 07:46
  • 1
    I’m voting to close this question because it doesn't indicate an actual problem being experienced. [Code Review](https://codereview.stackexchange.com) might be a better fit for this question. – Ortund Jan 22 '21 at 12:35
  • Thank you, i did not expect this much help. Although all answers were helpful, I marked the one that i felt best helped. This community is very helpful, and I appreciate all of the tips. – Holland_mike Jan 25 '21 at 02:14

3 Answers3

0

This works:

import java.io.*;
public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
        String s = "";
        String line = "";
        while((line = reader.readLine()) != null){
            s = s + line + "\n";
        }
        reader.close();
        s= s + " ";
        String word = "";
        char c = 0;
        for(int i= 0 ;i<s.length();i++){
            c = s.charAt(i);
            if(c == ' ' || c=='\n' || c=='\t' || c =='\r' || c=='\f' ){
                System.out.print(word.length()!=0?(word + "\n"):"");
                word = "";
            }else{
                word = word + c;
            }
        }
    }
}

Contents of test.txt:

hello world, this is a code.

Output:

hello
world,
this
is
a
code.
Jaysmito Mukherjee
  • 1,467
  • 2
  • 10
  • 29
0

As alternative to the other answers, here is a nice concise solution using Java 8 Streams:

Pattern word = Pattern.compile("\\s+");
try (Stream<String> lines = Files.lines(Paths.get("test.txt"), Charset.defaultCharset())) {
    lines.flatMap(line -> word.splitAsStream(line).filter(s -> ! s.isEmpty()))
         .forEachOrdered(System.out::println);
}

If you don't want to use Java 8 Stream, use the result of your search.

As I said in a comment earlier:

If you want words-by-whitespace instead of words-by-nonletter, just replace Character.isLetter(ch) with ! Character.isWhitespace(ch).

So here is the code from the question, with that change.

I also fixed newline issue in two places. See if you can spot where.

String s = "";
try (BufferedReader r = new BufferedReader(new FileReader("test.txt"))) {
    String line;
    while ((line = r.readLine()) != null) {
        s += line + '\n';
    }
}

boolean didCR = true;
for (int i = 0; i < s.length(); i++) {
    char ch = s.charAt(i);
    if (! Character.isWhitespace(ch)) {
        System.out.print(ch);
        didCR = false;
    } else {
        if (didCR == false) {
            System.out.println();
            didCR = true;
        }
    }
}
if (didCR == false) {
    System.out.println();
}
Andreas
  • 154,647
  • 11
  • 152
  • 247
-2

Reading the file is almost correct already, just add printing the words:

BufferedReader r = new BufferedReader( new FileReader( "test.txt" ) ); //create a buffer to read the file
String line;
while ((line = r.readLine()) != null) { //read each line one-by-one
    String[] words = line.split("\\s+"); //split at whitespace, the argument is a regular expression
    for( String word : words ) {
       //skip any empty string, see explanation below
       if( word.isEmpty() ) {
         continue;
       }

       //option 1: print each word on a new line
       System.out.println(word);

       //option 2: print words of a line still on one line
       System.out.print(word + " ");
    }

    //option 2: switch to a new output line
    System.out.println();
}

Note: either use option 1 or 2 to get the desired output.

A word on word.isEmpty():

Even though we use split("\\s+") to split on longer sequences of whitespace you still could get empty strings in the resulting array. The reason is that if a line starts with whitespace, e.g. A, you'd get the array ["", "A"] and you probably don't want to print that first empty string - so we check and skip those.

A word on split("\\s+"):

The parameter is a regular expression and "\\s+" means the expression \s (\ needs to be escaped in Java strings so we add another backslash).

\s is a character class meaning "any whitespace" and includes spaces, newlines, carriage returns etc. The + at the end is a quantifier meaning "one or more" and is used to split on longer sequences of whitespace as well. If you don't add that an input of A B (3 spaces) would result in ["A","","","B"].

If you want to split on spaces only, use " +".

Thomas
  • 87,414
  • 12
  • 119
  • 157