CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Oct 2008
    Location
    Indiana
    Posts
    56

    Need help manipulating StringBuffer

    I want to be able to read in a text file and then print it out. That in itself is fairly straight forward. But I also need to be able to eliminate a line of text if it starts with a certain character.

    Example text file to read in:

    Hello,
    How
    #are
    you
    doing
    today?

    I would like the output file to look like this (eliminate any lines starting with #):

    Hello,
    How
    you
    doing
    today?

    I thought the code below would do the job, but I get the error 'java.lang.StringIndexOutOfBoundsException: String index out of range: 0' and I'm not really sure why.

    Code:
    public StringBuffer readTextFile(String filename) {
    
            File file = new File(filename);
            StringBuffer contents = new StringBuffer();
            BufferedReader reader = null;
    
            try {
                reader = new BufferedReader(new FileReader(file));
                String text = null;
    
                // repeat until all lines are read
                while ((text = reader.readLine()) != null) {
    
                    if(text.charAt(0) == '#'){
                        // Do nothing (don't append to contents since line starts with #)
                    }
                    else {
                        contents.append(text).append(System.getProperty(
                            "line.separator"));
                    }
    
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return contents;
        }

  2. #2
    Join Date
    May 2009
    Posts
    2,413

    Re: Need help manipulating StringBuffer

    Quote Originally Posted by blinksumgreen View Post
    error 'java.lang.StringIndexOutOfBoundsException: String index out of range: 0' and I'm not really sure why.
    It's because the file has empty lines (no chars at all) and you still try to read a char from them. Change to,


    if (text.length() > 0 && text.charAt(0) == '#') {

  3. #3
    Join Date
    Oct 2008
    Location
    Indiana
    Posts
    56

    Re: Need help manipulating StringBuffer

    Thanks, that did the trick.

    I have one more question. I need to be able to print all string literals that appear in a file. The problem is that a line can contain multiple string literals.

    Example:

    "Hello, 'how' are 'you' 'doing'."

    I'd like it to print: how you doing

    I'm having a lot of trouble trying to figure this one out. Any hints?

  4. #4
    Join Date
    May 2009
    Posts
    2,413

    Re: Need help manipulating StringBuffer

    Quote Originally Posted by blinksumgreen View Post
    Any hints?
    You can use indexOf repeatedly to find ' in the string and then extract the literals using substring.

  5. #5
    Join Date
    Oct 2008
    Location
    Indiana
    Posts
    56

    Re: Need help manipulating StringBuffer

    Thank you for all the help!

  6. #6
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Need help manipulating StringBuffer

    An alternative approach (not that there is anything wrong with nuzzle's suggestion) would be to use the String.split("'") method to split the string at each apostrophe. This returns an array of strings where every other index contains the sub-string you require.

    To find the starting index you need to test the first character of the original string. If it is an apostrophe then your words start at index 0 ie they will be at 0, 2, 4, 6 etc. Else, if the first character is not an apostrophe then your words start at index 1 ie they will be at 1, 3, 5, 7 etc

  7. #7
    Join Date
    Oct 2008
    Location
    Indiana
    Posts
    56

    Re: Need help manipulating StringBuffer

    I ended up doing something kind of like that.

    When it reads in the file, if the beginning of the line starts with ! or does not contain a single quote, then it doesn't even bother appending it to the StringBuffer. Then it counts the single quotes and adds the locations to an array. Then it does a mod and grabs the substring of every i%2 and i+1.

    Code:
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    /**
     *
     * Reads in a text file and prints all literal strings within the file (ex. 'hello')
     * 
     */
    public class p03 {
    
        public static void main(String[] args) {
    
            p03 p = new p03();
    
            // reads the file in
            StringBuffer contents = p.readTextFile("example.txt");
    
            // print the literal strings in the file
            p.printStringLiterals(contents);
    
        }
    
        /*
         * reads in the file of choice and returns the contents as a StringBuffer
         *
         * with all the lines starting with '!' (comments) removed
         *
         * and all lines that do not contain a literal string removed
         */
        public StringBuffer readTextFile(String filename) {
    
            File file = new File(filename);
            StringBuffer contents = new StringBuffer();
            BufferedReader reader = null;
    
            try {
                reader = new BufferedReader(new FileReader(file));
                String text = null;
    
                // repeat until all lines are read
                while ((text = reader.readLine()) != null) {
    
                    boolean inThere = false;
                    // determine if the line has any literal strings
                    for (int i = 0; i < text.length(); i++) {
    
                        if (text.charAt(i) == '\'') {
                            inThere = true;
                        }
                    }
                    if (text.length() > 0 && text.charAt(0) == '!') {
                        // Do nothing (thus eliminating any commented lines, which begin with !
                    } else if (inThere == false) {
                        // Do nothing (thus eliminating any lines without literal strings)
                    } else {
                        contents.append(text).append(System.getProperty(
                                "line.separator"));
                    } // end else
                } // end while
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return contents;
        }
    
        /*
         * Takes in the pruned 'contents' and prints out the literal strings
         */
        public void printStringLiterals(StringBuffer contents) {
    
            String literalStrings = "";
            int[] locations;
            int counter = 0;
    
            // counts total number of occurances of ' so the array can be initialized
            for(int i = 0; i < contents.length(); i++){
    
                if(contents.charAt(i) == '\''){
                    counter++;
                }
            } // end for (counter now contains total number of --> ' <-- that appear
            
            locations = new int[counter]; // initializes the array of integers
            int position = 0; // allows the the location of the character to be loaded correctly
    
            // adds the locations of the single quotes to the array
            for(int i = 0; i < contents.length(); i++){
    
                if(contents.charAt(i) == '\''){
                    locations[position] = i;
                    position++;
                }
            }
    
            // finds the literal strings and appends them to the literalStrings string
            for(int i = 0; i < position; i++){
    
                if(i%2 == 0){
                    literalStrings = literalStrings + contents.substring(locations[i], locations[i+1]) + "'\n";
                }
            }
            System.out.println(literalStrings); // prints all literal strings that appear in the file
    
        }
    }

  8. #8
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Need help manipulating StringBuffer

    So what happens if the very first word is a string literal ie the first character is an apostrophe?

    BTW the code:
    Code:
     
                    boolean inThere = false;
                    // determine if the line has any literal strings
                    for (int i = 0; i < text.length(); i++) {
     
                        if (text.charAt(i) == '\'') {
                            inThere = true;
                        }
                    }
    Could be replaced with:
    Code:
     
                    boolean inThere = (text.indexOf('\'') >= 0);

  9. #9
    Join Date
    Oct 2008
    Location
    Indiana
    Posts
    56

    Re: Need help manipulating StringBuffer

    Quote Originally Posted by keang View Post
    So what happens if the very first word is a string literal ie the first character is an apostrophe?
    I think it would work just fine, why, does something not seem right in the code?

  10. #10
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Need help manipulating StringBuffer

    The only way to prove if code really works as intended is to run it with a full suite of possible inputs and check to see if the output is as expected. For example try the following inputs:

    <empty string>
    Hello, how are you doing
    'Hello', how are you doing
    Hello, 'how' are you doing
    Hello, 'how' are 'you' doing
    Hello, 'how' are 'you' 'doing'
    'Hello,''how''are''you''doing'
    'Hello'

    Note: This list is just an example of inputs to try it isn't supposed to be exhaustive

  11. #11
    Join Date
    Oct 2008
    Location
    Indiana
    Posts
    56

    Re: Need help manipulating StringBuffer

    Quote Originally Posted by keang View Post
    The only way to prove if code really works as intended is to run it with a full suite of possible inputs and check to see if the output is as expected. For example try the following inputs:

    <empty string>
    Hello, how are you doing
    'Hello', how are you doing
    Hello, 'how' are you doing
    Hello, 'how' are 'you' doing
    Hello, 'how' are 'you' 'doing'
    'Hello,''how''are''you''doing'
    'Hello'

    Note: This list is just an example of inputs to try it isn't supposed to be exhaustive
    I understand.

    Output:

    'Hello'
    'how'
    'how'
    'you'
    'how'
    'you'
    'doing'
    'Hello,'
    'how'
    'are'
    'you'
    'doing'
    'Hello'

    Output should be:

    'Hello'
    'how'
    'how'
    'you'
    'how'
    'you'
    'doing'
    'Hello,''how''are''you''doing'
    'Hello'


    In line 7 it reads all literal strings, but it should print the whole line out together. I'm not really sure how to deal with nested single quotes or an apostrophe being present.

  12. #12
    Join Date
    Oct 2009
    Posts
    1

    Re: Need help manipulating StringBuffer

    Just wondering, isn't BufferedReader deprecated since there's Scanner now?

  13. #13
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163

    Re: Need help manipulating StringBuffer

    Quote Originally Posted by pikaachi View Post
    Just wondering, isn't BufferedReader deprecated since there's Scanner now?
    No. The API Javadocs will tell you if a class is deprecated. The descriptions there will also tell you that they have entirely different functions.

    The Java Tutorials will tell you how they should be used: BufferedReader, Scanner.

    One can think effectively only when one is willing to endure suspense and to undergo the trouble of searching...
    J. Dewey
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

  14. #14
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    Re: Need help manipulating StringBuffer

    In line 7 it reads all literal strings, but it should print the whole line out together. I'm not really sure how to deal with nested single quotes or an apostrophe being present.
    This is one of the problems that occur when using a delimiter character that can also be part of the text. You can either choose a different delimiter character ie one that you know won't ever appear in the text or, if you can't do that, then you have to decide how you are going to differentiate between the character when used as a delimiter and when it's part of the text. A common way is to double up on the character when it's not a delimiter as per the example input text.

    When splitting, your code needs to check for and ignore double apostrophe characters, and then after the split it needs to replace all double apostrophe characters with a single one.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured