SOLUTION Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo() methods
First the code:
This part works fine: (pr(String s) <==> System.out.println(s))
pr("Stage:");
String stage = sc.next();
Stage st;
try{
st = Stage.valueOf(stage);
}
catch(IllegalArgumentException e){
inv();//Println "Invalid Input!"
break;
}
end then:
pr("End:");
String en = sc.nextLine();
LocalDateTime end;
try
{
int d = Integer.parseInt(en.substring(0,2));
int m = Integer.parseInt(en.substring(3, 5));
int h = Integer.parseInt(en.substring(7, 9));
int min = Integer.parseInt(en.substring(10));
end = LocalDateTime.of(year, m, d, h, min);
}
catch ( NumberFormatException f)
{
inv();//Prints Invalid Input!
break;
}
I get an
java.lang.StringIndexOutOfBoundsException: String index out of range: 2
at java.lang.String.substring(Unknown Source)
When debugging the scanner is always skipping the "End" input.
EDIT
en is "" but the input seems to be an infinite loop
(e.g: 12.11. 13:14 \n \n \n ...)
Therefore I cant save my input in en
EDIT2 Input is always "MM.dd. HH:mm" else print"Invalid Input"
How do I get rid of this problem? Is it caused by println?
The problem is: nextInt() ignores the "\n" character, therefore nextline() reads the rest of the line "\n".
Details: Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo() methods
Related
Question:
I have this set of number in a .txt document, I want to use java.util.Scanner to detect the line feed in between 123, 456, and 789, print out the numbers in between the line feeds, is there any way to do so?
1 2 3
// \n here
4 5 6
// \n here
7 8 9
Output:
456
===========================================================================
Solutions that I tried:
(1) I tried using hasNextLine() method, however, it seems like hasNextLine() will tell me are there tokens in the next line and return a boolean instead of telling me is there \n. if (scan.hasNextLine()) { \\ do something }
(2) I also tried using: (However, using such condition will say "Syntax error on token 'Invalid Character'")
Scanner scan = new Scanner(new File("test.txt"));
// create int[] nums
while (scan.hasNext()) {
String temp = scan.next();
if (temp == \n) {
// nums.add(); something like this
}
}
System.out.print(nums); // something like this
I am thinking using \n as delimiters
ps. I did google and most of the results tell me to use .hasNextLine(), but I want it to identify a line feed (\n)
Scanner scans the next element by using new-line or whitespace as a delimiter by default. To let it read the whole content use scan.useDelimiter("\\Z").
Scanner scan = new Scanner(new File("test.txt"));
scan.useDelimiter("\\Z");
final String content = scan.next(); // content: "1 2 3\r\n\r\n4 5 6"
int index = 0;
System.out.println("Index of \\n");
while (index != -1) {
index = content.indexOf("\n", index);
if (index != -1) {
System.out.println(index);
// Or do whatever you wish
index++;
}
}
Output:
Index of \n
5
7
I'm not sure I understand 100% your question. So I'm assuming your file always will have 2 lines separated by ONLY ONE new line(\n). If I'm wrong please tell it.
String charsAfterNewLine = null;
//try-catch block with resources
//Scanner need to be closed (scan.close()) after finish with it
//this kind of block will do `scan.close()` automatically
try(Scanner scan = new Scanner(new File("test.txt"))){
//consume(skip) first line
if(scan.hasNextLine()){
scan.nextLine();
}else{
throw new Exception("File is empty");
}
//get second line
if(scan.hasNextLine()){
charsAfterNewLine = scan.nextLine();
}else{
throw new Exception("Missing second line");
}
}catch(Exception e){
e.printStackTrace();
}
System.out.println("charsAfterNewLine: " + charsAfterNewLine);
If you want simple way, without try-catch:
String charsAfterNewLine = null;
//throws FileNotFoundException
Scanner scan = new Scanner(new File("test.txt"));
if(scan.hasNextLine()){
//consume(skip) first line
scan.nextLine();
if(scan.hasNextLine()){
//get second line
charsAfterNewLine = scan.nextLine();
}else{
System.out.println("Missing second line");
}
}else{
System.out.println("File is empty");
}
scan.close();
System.out.println("charsAfterNewLine: " + charsAfterNewLine);
Results(for both):
Input:
(empty file)
Output:
File is empty
charsAfterNewLine: null
-----
Input:
1 2 3 4 5 6
Output:
Missing second line
charsAfterNewLine: null
-----
Input:
1 2 3\n4 5 6
Output:
charsAfterNewLine: 4 5 6
while (scanner.hasNext()) {
String data = scanner.nextLine();
System.out.println("Data: " + data);
if (data.isEmpty()) {
System.out.println("Found it");
break;
}
}
I know that by default, the Scanner skips over whitespaces and newlines.
There is something wrong with my code because my Scanner does not ignore "\n".
For example: the input is "this is\na test." and the desired output should be ""this is a test."
this is what I did so far:
Scanner scan = new Scanner(System.in);
String token = scan.nextLine();
String[] output = token.split("\\s+");
for (int i = 0; i < output.length; i++) {
if (hashmap.containsKey(output[i])) {
output[i] = hashmap.get(output[i]);
}
System.out.print(output[i]);
if (i != output.length - 1) {
System.out.print(" ");
}
nextLine() ignores the specified delimiter (as optionally set by useDelimiter()), and reads to the end of the current line.
Since input is two lines:
this is
a test.
only the first line (this is) is returned.
You then split that on whitespace, so output will contain [this, is].
Since you never use the scanner again, the second line (a test.) will never be read.
In essence, your title is right on point: Java Scanner does not ignore new lines (\n)
It specifically processed the newline when you called nextLine().
You don't have to use a Scanner to do this
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String result = in.lines().collect(Collectors.joining(" "));
Or if you really want to use a Scanner this should also work
Scanner scanner = new Scanner(System.in);
Spliterator<String> si = Spliterators.spliteratorUnknownSize(scanner, Spliterator.ORDERED);
String result = StreamSupport.stream(si, false).collect(Collectors.joining(" "));
I have a .txt file and require its contents to be put into an arraylist.
It is in the following format, Each element(int,String) being on a new line within the document.
int number of parts
string partname
string description
int price
string partname
string description
int price
etc.
Whenever i run my program it will add the first however many attributes, but will not add the last three attributes to the arraylist.
public static void loadPartsCleanly(){
try {
// java.io.File file = new java.io.File("parts.txt");
Scanner in = new Scanner(new File("parts.txt"));
ArrayList<Part> partlist = new ArrayList<Part>();
String name=null;
String description = null;
double price =0.0;
int totalParts = 0;
totalParts = in.nextInt();
in.nextLine();
//totalParts ++ ;
System.out.println(totalParts);
for (int i = 0; i < totalParts; i++)
{
//ArrayList<Part> partlist = new ArrayList<Part>();
name = in.nextLine();
description = in.nextLine();
price = in.nextDouble();
in.nextLine();
int quantityInStock = 5;
partlist.add(new Part(name, description, price, quantityInStock));
System.out.println(partlist);
}
in.close();
} catch (FileNotFoundException fnfe) {
System.out.println("Unable to locate the parts.txt file for opening.");
} catch (Exception otherExc) {
System.out.println("***** An unexpected error has occurred *****");
otherExc.printStackTrace();
}
}
so in the above code it reads the first Int in the text document and assigns it for use in the for loop.
totalParts = in.nextInt();
in.nextLine();
//totalParts ++ ;
System.out.println(totalParts);
for (int i = 0; i < totalParts; i++)
The loop works fine up until the last part needs to be added to the arraylist, regardless of whether totalParts is 8 or 20.
Which gives this error..
An unexpected error has occurred java.util.NoSuchElementException: No
line found
I have been trying to figure this out but increasing frustration has prompted me to post on here, so any pointers in the right direction would be greatly appreciated. If you need clarification with anything regarding my question, please ask.
The nextInt() and nextDouble() methods are different than nextLine(). nextLine() reads the \n but the others.
So, if you have each element in a different line, you should use nextLine() always and then parse that line to the type that you want, for example:
String line = in.nextLine();
double price = Double.parseDouble(line);
I think the last line of your input file is a number.
What I saw from your code is that you use nextDouble to read the price and then you use nextLine to go to next line.
In such situation, if there is no more line behind the last number, you got error.
The following code solves your problem.
if (i + 1 < totalParts) {
in.nextLine();
}
I am trying to convert a string value taken from the keyboard into an int value. I have done it like this before but now I am getting an error which states NumberFormatException.forInputString
Scanner input = new Scanner(System.in);
String choice = "";
int numberChoice;
System.out.println("Please select one of the following options");
choice = input.nextLine();
numberChoice = Integer.parseInt(choice); /*I am getting the error on this line*/
The input code is:
Data[] temperatures = new Data[7];
for(int i = 0; i < temperatures.length; i++)
{
System.out.println("Please enter the temperature for day " + (i+1));
temperatures[i] = new Data(input.nextDouble());
}
you can use numberChoice = input.nextInt(); instead of choice = input.nextLine(); and then convert the string into integer
When you use a Scanner method that looks at one token, such as nextDouble() or nextInt(), the scanner will consume the characters in that token, but it will not consume the newline character at the end of the line.
This is fine if the next Scanner call is to another nextDouble(), nextInt(), etc., because then that call will skip over the newline.
However, if the next call is nextLine(), it will return "". nextLine() will return everything up to the next newline character; and since it hasn't yet consumed the newline character after the nextDouble() call, it will stop at that newline, and return an empty string, without giving you a chance to enter another line.
To solve this, you need to call an extra nextLine() to consume the newline:
for(int i = 0; i < temperatures.length; i++)
{
System.out.println("Please enter the temperature for day " + (i+1));
temperatures[i] = new Data(input.nextDouble());
}
input.nextLine(); // Add this to consume the newline
String choice = "";
int numberChoice;
System.out.println("Please select one of the following options");
choice = input.nextLine();
numberChoice = Integer.parseInt(choice);
Make sure you don't accidentally type in a space or a non-numeric character in your input line. I ran your code snippet and it works just fine.
Please select one of the following options
6546a
Exception in thread "main" java.lang.NumberFormatException: For input string: "6546a"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at PrimeNumbers.main(PrimeNumbers.java:12)
This should work fine, assuming you enter something that can be parsed as an int.
Wrap the offending line in a try block and output the error and the contents of choice to see what's going wrong
for example, try this:
try {
numberChoice = Integer.parseInt(choice);
}
catch (NumberFormatException nfe){
System.out.println("Failed to parse: ##"+choice+"##"); // mark off the text to see whitespace
}
on my machine, this produces
/Users/jpk/code/junk:521 $ java SO
Please select one of the following options
two
Failed to parse: ##two##
I have a scanner in my program that reads in parts of the file and formats them for HTML. When I am reading my file, I need to know how to make the scanner know that it is at the end of a line and start writing to the next line.
Here is the relevant part of my code, let me know if I left anything out :
//scanner object to read the input file
Scanner sc = new Scanner(file);
//filewriter object for writing to the output file
FileWriter fWrite = new FileWriter(outFile);
//Reads in the input file 1 word at a time and decides how to
////add it to the output file
while (sc.hasNext() == true)
{
String tempString = sc.next();
if (colorMap.containsKey(tempString) == true)
{
String word = tempString;
String color = colorMap.get(word);
String codeOut = colorize(word, color);
fWrite.write(codeOut + " ");
}
else
{
fWrite.write(tempString + " ");
}
}
//closes the files
reader.close();
fWrite.close();
sc.close();
I found out about sc.nextLine(), but I still don't know how to determine when I am at the end of a line.
If you want to use only Scanner, you need to create a temp string instantiate it to nextLine() of the grid of data (so it returns only the line it skipped) and a new Scanner object scanning the temp string. This way you're only using that line and hasNext() won't return a false positive (It isn't really a false positive because that's what it was meant to do, but in your situation it would technically be). You just keep nextLine()ing the first scanner and changing the temp string and the second scanner to scan each new line etc.
Lines are usually delimitted by \n or \r so if you need to check for it you can try doing it that way, though I'm not sure why you'd want to since you are already using nextLine() to read a whole line.
There is Scanner.hasNextLine() if you are worried about hasNext() not working for your specific case (not sure why it wouldn't though).
you can use the method hasNextLine to iterate the file line by line instead of word by word, then split the line by whitespaces and make your operations on the word
here is the same code using hasNextLine and split
//scanner object to read the input file
Scanner sc = new Scanner(file);
//filewriter object for writing to the output file
FileWriter fWrite = new FileWriter(outFile);
//get the line separator for the current platform
String newLine = System.getProperty("line.separator");
//Reads in the input file 1 word at a time and decides how to
////add it to the output file
while (sc.hasNextLine())
{
// split the line by whitespaces [ \t\n\x0B\f\r]
String[] words = sc.nextLine().split("\\s");
for(String word : words)
{
if (colorMap.containsKey(word))
{
String color = colorMap.get(word);
String codeOut = colorize(word, color);
fWrite.write(codeOut + " ");
}
else
{
fWrite.write(word + " ");
}
}
fWrite.write(newLine);
}
//closes the files
reader.close();
fWrite.close();
sc.close();
Wow I've been using java for 10 years and have never heard of scanner!
It appears to use white space delimiters by default so you can't tell when an end of line occurs.
Looks like you can change the delimiters of the scanner - see the example at Scanner Class:
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();