scanner.useDelimiter("\n\n") in java - java

I have a simple code to understand which reads a file (input2.txt) and displays it.
import java.util.*;
import java.io.*;
public class Test {
public static void main(String[] args ) throws Exception {
Scanner scanner = new Scanner(new File(args[0]) );
scanner.useDelimiter("\n\n");
String[] grid = scanner.next().split("\n");
scanner.close();
for(int row = 0; row < grid.length; row++) {
for(int col = 0; col < grid[row].length(); col++) {
System.out.print(grid[row].charAt(col) + " ");
}
System.out.println();
}
}
}
input.txt is
java Test input.txt is
What I don't understand is
scanner.useDelimiter("\n\n");
Why does it use two "\n\n" instead of one "\n"?
FYI, If I use scanner.useDelimiter("\n");
it doesn't work properly. This just read the first line from a file.

Your file contains newlines (\n) so setting delimiter to a single newline will cause next() to return the first line.
Since your files doesn't contain any blank lines, i.e. has no double newlines, next() will return the first token, which is the entire file content.
As to why someone chose \n\n? Who knows.
Also be aware that this won't work on Windows, where lines are separated by \r\n.

Setting the delimiter to \n\n will cause scanner.next() to return the entire file as one string, since there are no double new lines found. Setting the delimiter to anything that is never found would give the same behavior.
Next that string is split using split("\n") and the array will contain one entry per row from the file.
This can be written more cleanly like this
try (Scanner scanner = new Scanner(new File(args[0]))) {
while (scanner.hasNextLine()) {
String row = scanner.nextLine();
for (int col = 0; col < row.length(); col++) {
System.out.print(row.charAt(col) + " ");
}
System.out.println();
}
}

I don't understand why you are using split with a Scanner. The second makes what the first should.
Instead, use \n as a delimiter for your Scanner, but since you are using next(), this means you should iterate on the Scanner until there are no more to scan for.
The split is really making you lose all the interest of using a Scanner. You are just reading the whole file once and splitting it when it's all in-memory. This could cause memory exceptions with large files.
Untested but something like this should work:
import java.util.*;
import java.io.*;
public class Test {
public static void main(String[] args ) throws Exception {
Scanner scanner = new Scanner(new File(args[0]) );
scanner.useDelimiter("\n");
while (scanner.hasNext()) {
String row = scanner.next();
for(int col = 0; col < row.length(); col++) {
System.out.print(row.charAt(col) + " ");
}
System.out.println();
}
scanner.close();
}
}

Case 1 : You use scanner.useDelimiter("\n\n");
"\n\n" is a delimiter which was not found in the file so the first scanner.next() will give you the whole file !
And when you use .split("\n") on the whole file it will give you a array of elements found in the file splitted by "\n" this somehow made you think that your code is working.
import java.util.*;
import java.io.*;
public class Test {
public static void main(String[] args ) throws Exception {
Scanner scanner = new Scanner(new File(args[0]) );
scanner.useDelimiter("\n\n");
String[] grid = scanner.next().split("\n");
scanner.close();
for(int row = 0; row < grid.length; row++) {
for(int col = 0; col < grid[row].length(); col++) {
System.out.print(grid[row].charAt(col) + " ");
}
System.out.println();
}
}
}
Case 2: When you use scanner.useDelimiter("\n") scanner.next() returns you the first line as scanner has found a delimiter and is giving you the data line by line.
Now when you use scanner.next().split("\n"); the regex "\n" didn't match and again you got back the whole String that is the first row,which made you think your code isn't working.
If you want to read the file you should use scanner.hasNext() in a while loop as specified in some answer already.

By using the delimiter '\n\n' you tell the scanner to split tokens there. My assumption is that the input file is a Uninx style file (so line break is \n) which has two line breaks at the end or an empty line somewhere.
So the scanner.next() will basically return you a sting token up the the end (or empty line) and then splitt that by by line.
So a better way to do this would probably be:
Scanner scanner = new Scanner(new File(args[0]) );
scanner.useDelimiter("\n");
List<String> grid = new ArrayList<>();
while (scanner.hasNext()) {
grid(scanner.next());
}
scanner.close();
Your code will only handle the content of the file up to the point where there are two '\n\n'.

Related

Scanner for string does not work in Java [duplicate]

This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 6 years ago.
When I use scan.nextLine(), input boxes don't work properly. If it's scan.next() ,works perfectly.But Why? Ain't I supposed to use scan.nextLine() for string?
import java.util.Scanner;
public class Test{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int x = scan.nextInt();
System.out.println("p");
String p = scan.nextLine();
System.out.println("q");
String q = scan.next();
System.out.println("m");
String m = scan.next();
}
}
Before using them, try to check the doc's.
Reason :
Scanner.nextLine : The java.util.Scanner.nextLine() method advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present.
While, this is not Applicable to Scanner.nextInt
Hence, the Scanner.nextInt method does not consume the last newline character of your input, and thus that newline is consumed in the next call to Scanner.nextLine.
Basic Solution would be to use blank Scanner.nextLine after Scanner.nextInt just to consume rest of that line including newline.
For Example
int myVal1 = input.nextInt();
input.nextLine();
String myStr1 = input.nextLine();
This is the solution to the problem I'd use. The above comment by Tahir Hussain Mirwould likely be the cause of the problem
import java.util.ArrayList;
import java.util.Scanner;
public class app {
public static void main(String[] args) {
// declare scanner
Scanner scan = new Scanner(System.in);
// what ever number you need, it could be calculated
int numberOfInputLines = 3;
// the list of the lines entered
ArrayList<String[]> list = new<String[]> ArrayList();
// add each line to the list
for (int i = 0; i < numberOfInputLines; i++) {
// get entire line as a single string
String input = scan.nextLine();
// split the line into tokens, and store the array in the array list
String[] result = input.split("\\s");
list.add(result);
}
// iterate through each line
for (int i = 0; i < list.size(); i++) {
// iterate through the line
for (int j = 0; j < list.get(i).length; j++) {
if (isInteger(list.get(i)[j]) == true) {
// do what you want if the input is an int
//to show it works
System.out.println("int: " + list.get(i)[j]);
} else {
// do what you want if a the token inputed is a string
//to show it works
System.out.println("String: " + list.get(i)[j]);
}
}
}
}
// greasy way to check if is an int
private static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch (NumberFormatException e) {
return false;
} catch (NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
}
You should use nextLine and then convert it to your expected types.
In above scenario read the line then cast it to an integer, because next and nextInt just read the input before a whitespace occurred. So when you are calling nextInt it will just consume the number and leave the newLine character which will be consumed in nextLine.
From the question, it looks like this is how you are going to read inputs input.
First integer.
Second a string line.
Third line will have two words separated by space.
This is what your code should be.
Scanner scan = new Scanner(System.in);
int x = Integer.parseInt(scan.nextLine()); //read line and then cast to integer
System.out.println("p");
String p = scan.nextLine();
System.out.println("q m");
String[] linesParts = scan.nextLine().split(" "); // read the whole line and then split it.
String q = linesParts[0];
String m = linesParts[1];

No Line found error but I don't see how?

Pretty much I'm trying to write a program that counts the words in a text file AND count how many lines as well but I keep getting the no line error.
import java.util.*;
import java.io.*;
public class input {
public static void main(String[] args) throws FileNotFoundException {
String name;
int lineCount = 0;
int wordCount = 0;
File input = new File("C:\\Users\\Ceri\\workspace1\\inputoutput\\src\\inputoutput\\lab1task3.txt");
Scanner in = new Scanner(input);
while(in.hasNextLine()){
while(in.hasNext()){
wordCount++;
in.next();
}
lineCount++;
in.nextLine();
}
System.out.println(lineCount);
System.out.println(wordCount);
in.close();
}
}
The issue lays withing the while(in.hasnextline()) loop.
That is because your inner while loop exhasts all the input characters from your scanner. in.hasNext() does not stop at new line characters.
You are incorrectly implementing hasNextLine() and hasNext() such that you have read through all the tokens in your scanner within your inner while. An easier way to read every word and line would be to implement something like this:
int words = 0;
int lines = 0;
while(in.hasNextLine()) {
lines++;
String line = in.nextLine()
words += new StringTokenizer(line, " ,").countTokens();
}
You are reaching end of the file while looping through the inner loop. Once, it reaches the end of file, it will come out of inner loop. lineCount will be incremented and then, in.nextLine() will be executed. Buffer for Scanner's object is not having any value inside of it, hence you are getting this result.
Try this:
while(in.hasNextLine()){
String line = in.nextLine();
lineCount++;
String[] words = line.split(" ");
wordCount += words.length;
}
Do this
while(in.hasNextLine())
{
Scanner ins=new Scanner(in.nextLine());
while(ins.hasNext())
{
wordCount++;
ins.next();
}
lineCount++;
}

For loop iterating through string and adding/replacing characters

I need to write for loop to iterate through a String object (nested within a String[] array) to operate on each character within this string with the following criteria.
first, add a hyphen to the string
if the character is not a vowel, add this character to the end of the string, and then remove it from the beginning of the string.
if the character is a vowel, then add "v" to the end of the string.
Every time I have attempted this with various loops and various strategies/implementations, I have somehow ended up with the StringIndexOutOfBoundsException error.
Any ideas?
Update: Here is all of the code. I did not need help with the rest of the program, simply this part. However, I understand that you have to see the system at work.
import java.util.Scanner;
import java.io.IOException;
import java.io.File;
public class plT
{
public static void main(String[] args) throws IOException
{
String file = "";
String line = "";
String[] tempString;
String transWord = ""; // final String for output
int wordTranslatedCount = 0;
int sentenceTranslatedCount = 0;
Scanner stdin = new Scanner(System.in);
System.out.println("Welcome to the Pig-Latin translator!");
System.out.println("Please enter the file name with the sentences you wish to translate");
file = stdin.nextLine();
Scanner fileScanner = new Scanner(new File(file));
fileScanner.nextLine();
while (fileScanner.hasNextLine())
{
line = fileScanner.nextLine();
tempString = line.split(" ");
for (String words : tempString)
{
if(isVowel(words.charAt(0)) || Character.isDigit(words.charAt(0)))
{
transWord += words + "-way ";
transWord.trim();
wordTranslatedCount++;
}
else
{
transWord += "-";
// for(int i = 0; i < words.length(); i++)
transWord += words.substring(1, words.length()) + "-" + words.charAt(0) + "ay ";
transWord.trim();
wordTranslatedCount++;
}
}
System.out.println("\'" + line + "\' in Pig-Latin is");
System.out.println("\t" + transWord);
transWord = "";
System.out.println();
sentenceTranslatedCount++;
}
System.out.println("Total number of sentences translated: " + sentenceTranslatedCount);
System.out.println("Total number of words translated: " + wordTranslatedCount);
fileScanner.close();
stdin.close();
}
public static boolean isVowel (char c)
{
return "AEIOUYaeiouy".indexOf(c) != -1;
}
}
Also, here is the example file from which text is being pulled (we are skipping the first line):
2
How are you today
This example has numbers 1234
Assuming that the issue is StringIndexOutOfBoundsException, then the only way this is going to occur, is when one of the words is an empty String. Knowing this also provides the solution: do something different (if \ else) when words is of length zero to handle the special case differently. This is one way to do this:
if (!"".equals(words)) {
// your logic goes here
}
another way, is to simply do this inside the loop (when you have a loop):
if ("".equals(words)) continue;
// Then rest of your logic goes here
If that is not the case or the issue, then the clue is in the parts of the code you are not showing us (you didn't give us the relevant code after all in that case). Better provide a complete subset of the code that can be used to replicate the problem (testcase), and the complete exception (so we don't even have to try it out ourselves.

What's wrong with this file Scanner code?

I am trying to search the File for characters in Java language. For that I am using Scanner to scan the file.
Well to check the Heirarchy work, I am using System.out.print("Worked till here!"); so that I can check whether it is executed or not. I was able to execute the code till the last stage, but then I found that the essential boolean variable wasn't altered, which was under the condition to check whether there is a character match or not.
The file contents are as
Ok, here is some text!
Actually this file is created to test the validity of the java application
Java is my favourite programming language.
And I think I can score even more :)
Wish me luck!
However, no matter what I search it always prompts me to be false.
Here is the code I am using
public static void main (String[] args) throws IOException {
// Only write the output here!!!
System.out.print("Write the character to be found in the File: ");
Scanner sc = new Scanner(System.in);
String character = sc.next();
// Find the character
System.out.println("Searching now...");
getCharacterLocation(character);
// Close the resource!
sc.close();
}
The method call executed and the method is as
public static void getCharacterLocation (String character) throws IOException {
System.out.println("File found...");
File file = new File("res/File.txt");
Scanner sc = new Scanner(file);
int lineNumber = 0;
int totalLines = 0;
boolean found = false;
// First get the total number of lines
while(sc.hasNextLine()) {
totalLines++;
sc.nextLine();
System.out.println("Line looping! For Total Lines variable.");
}
int[] lineNumbers = new int[totalLines];
int lineIndex = 0;
System.out.println("Searching in each line...");
while(sc.hasNextLine()) {
// Until the end
/* Get each of the character, I mean string from
* each of the line... */
while(sc.hasNext()) {
// Until the end of line
String characterInLine = sc.next();
if(sc.findInLine(character) != null) {
found = true;
}
}
System.out.print(sc.nextLine() + "\n");
lineNumber++;
sc.nextLine();
}
System.out.println("Searching complete, showing results...");
// All done! Now post that.
if(found) {
// Something found! :D
System.out.print("Something was found!");
} else {
// Nope didn't found a fuck!
System.out.println("Sorry, '" + character +
"' didn't match any character in file.");
}
sc.close();
}
Never mind the extra usage of variables, and arrays. I would use it in further coding if I can get the character and set the value to true.
Here is the output of this program.
Initial Stage
This is the initial stage for that. I wrote Ok in the input field, you can see Ok is the very first character in the File too.
Final Stage
This is the result after the execution.
Any help in this?
You count lines and don't restart the scanner.
boolean found = false;
// First get the total number of lines
while(sc.hasNextLine()) {
totalLines++;
sc.nextLine();
System.out.println("Line looping! For Total Lines variable.");
}
int[] lineNumbers = new int[totalLines];
int lineIndex = 0;
System.out.println("Searching in each line..."); // <------
while(sc.hasNextLine()) {
add e.g.
UPDATED from the comment
sc.close();
sc = new Scanner(file);
before the next while(sc.hasNextLine())
You need to implement a way to string your characters together and check them against your input. It appears that you don't currently have a way to do this in your code.
Try building an array of characters with your scanner, and moving through and doing a check of your input vs the indexes. Or maybe there is a way to implement the tonkenizer class achieve this.
Put remember, what you are looking for is not a character, it is a string, and you need to keep this in mind when writing your code.
When you count your lines you use while(sc.hasNextLine()).
After this loop, your scanner is behind the last line, so when you go to your next loop while(sc.hasNextLine()) { it is never executed.
There are multiple problems with your code:
You Iterated through your scanner here:
while(sc.hasNextLine()) {
totalLines++;
sc.nextLine();
System.out.println("Line looping! For Total Lines variable.");
}
So after this you have to reset it again to read for further processing.
While searching for character you are having two loops:
while(sc.hasNextLine()) {
// Until the end
/* Get each of the character, I mean string from
* each of the line... */
while(sc.hasNext()) {
// Until the end of line
String characterInLine = sc.next();
if(sc.findInLine(character) != null) {
found = true;
}
}
Here you just need a single loop like:
while(sc.hasNextLine()) {
String characterInLine = sc.nextLine();
if(characterInLine.indexOf(character) != -1) {
found = true;
break;
}
}

Using charAt in java

This is my assignment:
Write a program where the user enters a string, and the program echoes it to the monitor with one character per line:
C:\>java LinePerChar
Enter a string:
Octopus
O
c
t
o
p
u
s
I have tried, but I'm getting some compilation errors. Here's my code:
import java.util.*;
class CharactorEcho{
public static void main(String args []){
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string :");
try {
String inputString = sc.nextLine();
for(int i=0; i < sc.length(); i++) {
char c = inputString.charAt(i);
System.out.println("" + c);
}
} catch(IOException e) {
}
}
}
In your loop, you should be looping over the length of the String that you get from the Scanner.nextLine, not the scanner itself.
for(int i=0; i<inputString.length(); i++){
If you want the input to be echoed with each character on the same line, use System.out.print instead of println.
Two Issues:
Change for(int i=0; i<sc.length(); i++){ to for(int i=0; i<inputString.length(); i++){
You care comparing against the scanner and not the input string.
Also, please try catching
java.util.NoSuchElementException
java.lang.IllegalStateException
in place of IOException, as your statement sc.nextLine() with throws NoSuchElementException and IllegalStateException, not IOException.
Make sure you add the related import statements.
You need to import IOException. Add this line to the top of your code, just after the package line if you have one:
import java.io.IOException;
Also, you're asking sc for a length instead of the string, so change your for to this:
for(int i = 0; i < inputString.length(); i++) {
Really though, you shouldn't be catching IOException. In fact, your code will never throw an exception. This is really all you need:
public static void main(String args []){
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string :");
String inputString = sc.nextLine();
for(int i=0; i < sc.length(); i++) {
char c = inputString.charAt(i);
System.out.println("" + c);
}
}
Calling nextLine on a Scanner made with System.in will only throw an exception if System.in isn't accessible, and it won't even be an IOException, so don't worry about it.
One final observation, you don't need to do "" + c in your println. System.out has a println method specifically for char, so you can just call:
System.out.println(c);

Categories

Resources