• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Liutauras Vilda
  • Knute Snortum
  • Bear Bibeault
Sheriffs:
  • Devaka Cooray
  • Jeanne Boyarsky
  • Junilu Lacar
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
  • salvin francis
Bartenders:
  • Tim Holloway
  • Piet Souris
  • Frits Walraven

How to read a string from console?

 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hey everyone!
i have this problem where i have to calculate frequency of characters 'A' and 'D' in a string containing only these two characters and later comparing them in different test cases.
When i compiled it in intellij, i was not able to read string from console.....instead i was getting "AdiDan" as output everytime.I don't get what am i doing wrong.Am i not using correct method to read a string from console?
 
Marshal
Posts: 68069
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How do you know you can't read any text from the console? Please tes‍t your program by printing the input back.

Also find out what the nextLine() method actually reads. There is a poorly‑documented pitfall somewhere.
 
Ranch Foreman
Posts: 124
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I recommend instead of doing this:

To do this:

Sometimes nextInt() fails to consume the new line character at the end of the input.

This condition is dangerous:

What if the user enters -1?
I would prefer to check while (tc > 0). Or even better, for(int j = 0; j < tc; j++)

Some more general stuff:
- Try to name your variables with more meaningful names; what is "tc"? What is "no_of_A"? If you name variables better, you don't need some of those comments you have now that explains the variable.
- In Java, typically camelCase is used for writing variables/method names. For example, "noOfA"
- It's a good idea to prompt the user before asking for input via scanner: for example System.out.print("Enter number of test cases: ");
- It's not necessary to declare a variable for 'A' and 'D' before comparing.
 
Campbell Ritchie
Marshal
Posts: 68069
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Zachary Griggs wrote:I recommend instead of doing this:

To do this:

I think I would disagree; use the capabilities of the Scanner object.

Sometimes nextInt() fails to consume the new line character at the end of the input. . . .

Actually, the problem is the other way round; nextInt() doesn't consume the following whitespace, which includes line end sequences.

Some more general stuff: . . .

Now, that bit's good
 
Zachary Griggs
Ranch Foreman
Posts: 124
11
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, but I don't agree. nextInt and similar methods have the unexpected effect of not consuming the newline entered after them, which causes the nextLine after it to only pick up the newline and get basically nothing.

Actually, the problem is the other way round; nextInt() doesn't consume the following whitespace, which includes line end sequences.


That's what I said :P

nextInt() fails to consume the new line character at the end of the input.



This is a major point of confusion for beginners to java.
See all the people who have a problem with this behavior (OP of this post included). You get hundreds of these questions if you google it from people who use the scanner methods without fully understanding the effects of it.
https://stackoverflow.com/questions/13102045/scanner-is-skipping-nextline-after-using-next-or-nextfoo
https://www.geeksforgeeks.org/why-is-scanner-skipping-nextline-after-use-of-other-next-functions/
https://www.daniweb.com/programming/software-development/threads/232053/nextline-after-nextint-or-nextdouble-gives-trouble
https://www.edureka.co/community/5931/scanner-is-skipping-nextline-after-using-next-or-nextfoo
Hundreds of people have this issue. The simplest solution is to just use nextLine.
The behavior of it is what people expect from their input-reading class. People don't expect the nextLine() after next() to returns nothing. Using only nextLine() never leads to confusing glitches like this, while if you use the other next methods, you always need to keep in mind that you have to get rid of the following newline.
You can also use nextInt() and then nextLine() and then nextLine() again - where the second nextLine() returns what you want.

This also lets you perform some custom validation on the input if desired, rather than just immediately failing.
For example if you ask the user to enter a money value, you might check if the string they entered starts with $ and remove it before parsing into an integer.
When you use the native nextInt() functionality, you simply exception out

When should you use nextInt() and the such? When you are trying to read multiple ints on a single line.
For example: the user enters the width and height of an image like "500 600" then you can call nextInt() twice and it works well
And if you didn't, you'd have to perform a split.
 
Campbell Ritchie
Marshal
Posts: 68069
258
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Zachary Griggs wrote:. . .That's what I said :P

You said sometimes. It cannot consume the line end sequence and return an int; if it consumes the line end sequence it will fail to parse the number correctly and throw an exception. A nextInt() call that actually works always leaves the line end sequence in the input buffer.

. . . This is a major point of confusion for beginners to java. . . . .

That is because most book authors don't know how nextLine() works. And probably most teachers don't know either. Because there are so few decent tutorials about nextLine(). Because it is a badly‑named method. Because people use a Scanner object directly rather than wrapping it in a utility class which verifies all the inputs, and can repeat the input until it is in the correct format. In the case of nextLine() a utility method can reject empty lines.
There is a simpler solution than writing a utility class; you have to discard the remainder of the line by calling newLine() twice, but that doesn't make the code look at all pretty. You only use the second line read.

If you look up nextLine(), you will find it tells you exactly what it does, and whether it consumes the line end sequence. If you use nextInt() you can enter the two numbers on the same line or separate lines and have them both read correctly.
 
Aditya Agrawal
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
what is a utility method?
 
Zachary Griggs
Ranch Foreman
Posts: 124
11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A utility method would be creating another class (something like ConsoleUtils or ConsoleHelpers) that uses a scanner and ensures that the usage of scanner is safe. It would define methods to read an int, string, etc. and also methods to read more complex data types or objects as needed. Then your java program would exclusively use this utility class rather than directly using a Scanner.

The point of it is to abstract the logic of reading the input away from Scanner and into something that makes sense based on the context of your application. And to ensure that data is read in a safe manner (that won't crash). Basically a complex wrapper around Scanner. And when you do this, you can also make it more abstract than JUST being around Scanner. You can make this Utility class adaptable to any kind of input source you want. As long as your whole program goes through your utility layer, you only need to change it in one place.

Do you need to do this for java school projects? No. But you can if you want to. And then maybe you can even re-use your console utility class over and over and save some work in the long run.
 
Aditya Agrawal
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i'm just a learner and has limited experience in programming.I'm learning java from 2 months and i really wanna get a hang of oop concepts.
so,  int tc = Integer.parseInt(sc.nextLine()); will take the cursor to new line.
thanks for your help!
 
Campbell Ritchie
Marshal
Posts: 68069
258
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Zachary Griggs wrote:A utility method would be . . . .

. . . something really useful. In this case, it will read an int from the keyboard it you writeAs ZG says, it will take care of all the corner cases, to ensure you really get an int without any problems. I have one just like that, only I call it KeyboardInputs, and I use it for keyboard input. It is, as ZG says, a wrapper round a Scanner object. I chose to use mine for keyboard input only, and to maintain the default delimiter for the Scanner unchanged (see the Scanner documentation), but other people might design their own utility classes differently.
Utility classes usually have the following characteristics:-
  • 1: All their members are marked static.
  • 2: It is therefore not necessary ever to create instances of this class, so they have a private constructor (see the JLS =Java┬« Language Specification).
  • 3: Some utility classes exist to provide constant values for other code.
  • 4: Some utility classes exist to provide methods for other code.
  • 5: Some utility classes exist to provide constant values and methods for other code.
  • Look at the java.lang.Math class, which is a typical utility class. I think that “utility class” is a sort of design pattern. Note utility classes often have plural names, whereas ordinary classes have singular names.
    My keyboard input class is based on the premise that the following loop, which Rob Spoor taught me, will take input from the keyboard without ever causing this exception to be thrown.You avoid other exceptions by never closing that Scanner, nor using ctrl‑D/ctrl‑Z which might both close System.in. I tried to make my input t‍hread‑safe and failed; I shall leave threa‍d‑safety as an exercise for other readers. I have various versions; in this version I am modelling the method names on the similar methods in Scanner. Other people will want to design their classes differently. You can use such a loop like this:-No hashCode() nor equals() nor toString() methods because they can only be called on instances. Note the two overloaded versions of nextInt(); one allows you to specify values in a certain range. A next() method would be simpler; there is no need to test whether there is a “next token“ because System.in implicitly always has a “next token“. I have had various versions of my nextLine() method over the years. If you use Java≤10, change strip() to trim() because strip() is only available in Java11+.
    You would need comprehensive documentation comments. You can create methods to read different types, e.g. nextBigDecimal() or nextLong(). Reading booleans is not quite the same, but similar enough that you should be able to work it out for yourself.

    Zachary Griggs wrote:. . . your java program would exclusively use this utility class . . . re-use your console utility class over and over and save some work in the long run.

    Agree whole‑heartedly, except that it won't save you some work; it will save you lots and lots of “work in the long run”. By the time you have written loops like that above in ten places in your code, you will have spent more time than if you had written an input utility class, and also written lots of duplicated code.
     
    Something must be done about this. Let's start by reading this tiny ad:
    Java file APIs (DOC, XLS, PDF, and many more)
    https://products.aspose.com/total/java
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!