Java Coding help

Discussion in 'Mac Programming' started by Rodimus Prime, Jun 19, 2010.

  1. Rodimus Prime macrumors G4

    Rodimus Prime

    Joined:
    Oct 9, 2006
    #1
    I have been coding a project for class am on one small part of the project that I can not figure out how to do.

    The problem I am having is trying to figure out how to take string and pull numbers out of it and skip the other chars.
    For example the user would enter "5 - 20"
    I would take that and have pull out an int 5 and and int 20.

    I just can not figure how to do it. If it was just one number it would be easy but pulling 2 different numbers out of the string is what is killing me.

    Any help would be great.
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    Break it down.
    http://www.cocoadev.com/index.pl?BreakItDown

    How would you break down the "5 - 20" into separate parts?

    Hint: (white text between brackets)
    [ java.util.StringTokenizer ]


    I've also asked the mods to move this thread to the Mac Programming forum.
     
  3. Cromulent macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #3
    Java has some pretty strong string processing abilities in its standard library (not sure which version they came in though) a quick browse of the Javadocs for Java 6 should highlight the specific classes you'll want.
     
  4. mrbash macrumors 6502

    Joined:
    Aug 10, 2008
    #4
    Reading a line of text from left to right. What are the possible cases you might encounter? Think of this as a state machine
     
  5. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #5
    Rodimus, a number is only a sequence of one or more digits?

     
  6. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #6
    If one number is easy, then I assume you're using a Scanner object to do it. If so look into the methods
    nextInt
    hasNextInt
    skip
     
  7. mrbash macrumors 6502

    Joined:
    Aug 10, 2008
    #7
    This is a "class project" so I think the method of deconstruction the input into a number of states is the point. While there are many useful APIs that could help, I don't think that would be the point of the lesson.

    Here are some more hints about the states:
    s0 -> first char is a non-number
    s1 -> first char is a number
    s2 -> previous char is a number, current char is a non-number
    s3 -> previous char is a number, current char is a number

    Constructing a state machine via switch statements may be the point of the exercise. I would wager that the next exercise would be to take this and do it via regex.
     
  8. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #8
    a way to do it in C

    I haven't meant to write our friend's program. My function is in C, not in Java, and that function isn't object-oriented.
    Code:
    /* Create a list of any integers you find in the text. */
    
    static int get_integers_from(const char text[], int integers[], const int list_capacity)
    {
      register int how_many = 0, next_integer;
    
      while (sscanf(text, "%d", &next_integer) == 1 && how_many < list_capacity)
        integers[how_many++] = next_integer;
      return how_many;
    }
     
  9. mrbash macrumors 6502

    Joined:
    Aug 10, 2008
    #9
    Bill,

    While the syntax for C and Java are similar the APIs are a bit different. In particular there is no direct equivalent to scanf/printf; but those functions are also discouraged in cpp and for good reason.

    Also, I would encourage you to review that alarmingly dangerous snippet of code you presented. I'm sure there are some implied safeguards but our impressionable friends being novice programmers may not realize that.
     
  10. macjunk(ie) macrumors 6502a

    Joined:
    Aug 12, 2009
    #10
    if the users enter the strings in a pattern, you can use Java's pattern/matcher classes to do your bidding...
     
  11. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #11
    Thanks for the warning, mrbash. I shouldn't have posted that snippet, partly because I hardly know C. What's frighteningly dangerous about the function I thought up while I wrote its post? I certainly don't want to teach our friends any bad programming-techniques. I didn't know that I wrote dangerous code.

    Anyhow your comment about my alarmingly dangerous snippet reminds that whatever is dangerous about my function, C's permissiveness is probably partly to blame for the danger.

    Let me try to explain my function a little. Sscanf reads numbers, strings, characters, and maybe even data of other types, from strings. I compare sscanf's value to one because when that value is one, that means that the computer has just read one integer from the string. If that function's value is not one, and if no runtime error has occurred, a function value other than one should mean that the computer can't find any, or perhaps any more, integers in the string.

    I don't know C++, and I haven't learned Java. Nowadays, I do functional programming.

    Bill
     
  12. winninganthem macrumors 6502a

    winninganthem

    Joined:
    Jun 10, 2008
    #12
    I won't code it for you, but here's a way of thinking about your problem that might help. :)

    1. Create temporary strings called result_1 and result_2 to store your results.

    2. Read the input string character by character.

    3. If the current character is a number, append it to result_1.

    Otherwise, if the current character is non-numeric, do nothing and read the next character.

    4. After dealing with the non-numeric characters in the middle of the input string, if the next character is a number, append it to result_2. Continue until there are no characters left.

    5. Convert result_1 and result_2 from strings to integers.

    Tip:
    Use the parseInt method from the Integer class to turn Strings into integers.
    Example:
    Code:
    String someString = "23";
    int result = Integer.parseInt(someString);
    System.out.println(result);    // will print 23.
    
    If someString is not a number, parseInt will throw a NumberFormatException, which is probably out of the scope of your assignment, but, give us an update on how you're doing.
     
  13. sanPietro98 macrumors 6502a

    sanPietro98

    Joined:
    May 30, 2008
    Location:
    28.416834,-81.581214
    #13
    Take a look at the class java.io.StreamTokenizer
     
  14. mrbash macrumors 6502

    Joined:
    Aug 10, 2008
    #14
    The OP will probably be best served with an explanation of a solution rather than code that they can cut/paste.

    The array you provide as a parameter is assumed to be allocated before hand, but no check is made to ensure that it is. Further, there is no indication of the size of the array that you presume to be allocated. This is very much playing Russian Roulette.

    While you could provide an implementation like:
    (let ((inputstr (read)))
    (def integerlist '())
    (let ((pos 1))
    (loop
    (when (> pos (length inputstr) )
    (multiple-value-setq (integer pos) (parse-integer inputstr :start pos :junk-allowed t) )
    (push integer integerlist)
    )
    )
    )
    integerlist
    )

    He may be better served with an explanation of how a function like the one below could be used to construct a list of integers:
    (parse-integer inputstring :start 0 :junk-allowed t)

    That whole "give a man a fish" VS "teach a man to fish" thing.
     
  15. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #15
    I'm sorry I wrote the function. In fact, I'm not even sure why I wrote it. Since our friend is programming in Java, a language that doesn't have a sscanf function, my code probably wouldn't have helped, even if it were safe.

    My only excuse for assuming that the parameter's memory is already allocated is that, in some C books I've read, authors have assumed the same thing in some functions they wrote in those books. They used the array notation instead of pointer notation because they thought array notation more readable than pointer notation. I should replace the array notation with pointer notation and check whether the computer has allocated memory for the array. But again, I merely imitated what some authors wrote.

    I wasn't trying to do anyone's else's homework for him.



    I'll write another code fragment, partly because it doesn't extract integers from a string. To create a list of integers that come from another list that may or may not contain any integer, in Scheme, I would write something like this:

    Code:
    (define (integers-from this-list)
             (filter integer? this-list))
    Scheme's memory management is automatic. So this Scheme function isn't dangerous.
     
  16. Rodimus Prime thread starter macrumors G4

    Rodimus Prime

    Joined:
    Oct 9, 2006
    #16
    Tell you truth I end up doing something like that.

    I first had it replace the '-' with a " " then I used the tokenizer. I put the space in there to make sure it had a break point. Fro
    There I used a loop and a had a try catch function to check to see if it was a integer.
    I know what I did was more of a brute force method so I would meet the requirements of the project but it still felt very messy to me.

    Not my favorite way of doing things and I personly feel it is bad pratice to do thing that way but I was out of time so I went that way.

    I have to say thank you all for the help and pointing me in the right direction.
     
  17. BigJimSlade macrumors member

    Joined:
    Dec 16, 2005
    #17
    Really?

    It's mildly terrifying that the words "regular" and "expression" are not mentioned once in this thread.
     
  18. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #18
    Not really. Because someone who has to ask about how to tokenize a String is unlikely to understand regex.
     
  19. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #19
    You could have created a StringTokenizer where the delimiters contained '-' and space. That would be a little simpler because you wouldn't need to call replace().

    A try/catch is a perfectly good way to catch errors. That's what it's for.

    If you want additional comments on your code, you'll have to post it.
     
  20. Rodimus Prime thread starter macrumors G4

    Rodimus Prime

    Joined:
    Oct 9, 2006
    #20
    I was and still am my iPod touch and do not have direct access to my code. That delimited sounds like a better way of doing it. I was reading the API and they are saying that something like split should of been used and the tokenizer is legacy code. I mix and match examples I was finding online and modifided them to work with what I needed. The tokenizer but pointed me in the right direction to look for something that would work. Heck it gave me another used for my try catch method I had programed in for another part of my program.
    I learning quickly why some bugs are left because even in my 500 lines of code I know how mich I struggled to find some of the annoying little bugs.
     
  21. mrbash macrumors 6502

    Joined:
    Aug 10, 2008
    #21
    Now that the original issue is resolved, I guess there is no harm in presenting a solution.

    RegEx is the way to go, as I mentioned in my original post.

    Code:
    System.out.println("Enter some text: ");
    try{
        String input = new BufferedReader( new InputStreamReader(System.in)).readLine();
    
    /*** LOOK HERE ******/
        String [] parts = input.split("-");
        java.util.regex.Pattern p = java.util.regex.Pattern.compile("\\d+");
        for(String part : parts) {
            part = part.trim();
            if( p.matcher(part).matches() )
                System.out.println(part);
        }
    /*** END ******/
    }catch(IOException ex){
        ex.printStackTrace();
    }
    
     
  22. macjunk(ie) macrumors 6502a

    Joined:
    Aug 12, 2009
    #22
    I was thinking the same actually...:)
     
  23. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #23
    Thank you again, mrbash, for warning me about what I assumed when I wrote the C function that collected integers from a string. I can see why my code would have alarmed some programmers. But since I always like to back up what I say when I write about books I've used, here's a link to code from a book where the author declares a function's dummy array-arguments the way I declared mine. The answer's come from the book's second edition, but I used its first edition instead.

    http://knking.com/books/c2/answers/c13.html

    Bill
     
  24. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #24
    It's not that you used the array notation. It's that the string being parsed can contain more values than the output array has space to hold. You neglected to provide a limiting count for the size of the output array.

    C's arrays are essentially unbounded on either end. Overflows and underflows do not cause detectable compile or runtime errors. They just overflow until some other damage is done, sufficient to crash the program or destroy other values. Look at the difference between lib functions strcat(), strncat(), strlcat().
     
  25. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #25
    Thank you for the excellent points, my friend. See what I get for programming mostly in languages much higher-level than C? I ignore details I should have considered. To bad I didn't remember how dangerous the gets() function can be. I'll think much more thoroughly before I write another C function.
     

Share This Page