How to determine the end of a line with a Scanner? - java

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();

Related

Trying to appending a text in a new line to an existing file in Java?

How to append text to an existing file in Java?
I am using the method mentioned in the solution and i am taking user input.
But the text is appending with the last word. is there any way to add an new line there?
Scanner sc= new Scanner(System.in);
System.out.print("Enter a string: ");
String str= sc.nextLine();
try {
Files.write(Paths.get("C:\\Users\\souravpal\\Documents\\Bandicam\\buddy.txt"), str.getBytes(), StandardOpenOption.APPEND);
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
You must use the new line character \n in your str variable if you want to move to the next line.
String str = "\n" + sc.nextLine();
You also should put it before the input becouse you will append it at the end of the file.
use the System.lineSeparator() constant that applies at runtime and compatible with all OS.
Files.write(Paths.get("C:\\Users\\souravpal\\Documents\\Bandicam\\buddy.txt"),
(System.lineSeparator() + str).getBytes(),StandardOpenOption.APPEND);

Java Scanner does not ignore new lines (\n)

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(" "));

Skip empty row in CSV file using Java

I am using the Scanner method to read the csv file in Java. And wish to skip the empty row in the output.
What method should I use?
Scanner s=new Scanner(new File("file location"));
s.useDelimiter(",");
while(s.hasNext()){
System.out.print(s.next());
System.out.print("|");
System.out.print("\t");
}
s.close();
If a row is empty it will contain (col - 1) delimiters in that line of the file.
For example, with 5 columns, an empty row would be line 2, with (5-1)=4 delimiters:
line1: 5,4,3,2,1
line2: ,,,,
line3: 1,2,3,4,5
So scan in each line, split by delimiter, and ignore unless the length of the line is greater than number of columns - 1.
Scanner s=new Scanner(new File("file location"));
while(s.hasNextLine()){
String line = s.nextLine();
String[] cols = line.split(",");
// if every col is empty, the line will equal col-1 delimiters.
if(line.length() > cols.length - 1){
for(String str : cols){
System.out.print(str);
System.out.print("|");
System.out.print("\t");
}
}
}
s.close();
You could go through file lines by nextLine (and his has* part), check for emptiness and split the string by your delimiter.
If you try to print length for s.next() you can figure out what is causing this. It is caused of end of line characters \r and \n. So, removing them will give the desired result.
Scanner s=new Scanner(new File("1.csv"));
s.useDelimiter(",");
String contentRead="";
while(s.hasNext()){
contentRead = s.next().replaceAll("\\r","");
contentRead = contentRead.replaceAll("\\n","");
if(!contentRead.isEmpty()){
System.out.print(contentRead);
System.out.print("|");
System.out.print("\t");
}
}
s.close();
Use below code to solve your problem and skip empty line while reading CSV using Scanner
String line = "";
while (s.hasNext()) {
if (!(line = s.nextLine()).isEmpty()) {
System.out.print(line);
System.out.print("|");
System.out.print("\t");
}
}
There is no method available in Scanner class to achieve this.
here, rather than using "," as delimiter, use "\n" as delimiter.
This will help you get a particular line contents in each iteration.
Then you can verify if content of that particular line suit you and proceed as required.
s.useDelimiter("\n");
while(s.hasNext())
{
line = s.next();
System.out.println("\nNext Line :" +line);
//Here, tokenize the line and verify if any non-empty token exists
}
CSV can be tricky:
individual values may contain a newline separator (e.g. v1, "v2[\n]and a new line", v3): if you use a nextLine() equivalent you won't parse the data correctly.
individual values may contain the delimiter (e.g. v1,"v2[,] and more stuff", v3): in this case simply relying on a split() equivalent will produce multiple values instead of one.
Line breaks won't be handled properly in multiple platforms (e.g. v1 "v2[\r\n]and a new line", v3): if you parse this in Linux or MACOS the second column will be parsed to produce a blank line between v2 and and a new line (i.e. you'll get 3 lines instead 2).
Use a the CSV parser that comes with uniVocity-parsers to handle these sorts of situations reliably:
CsvParserSettings settings = new CsvParserSettings(); // many options here, check the tutorial.
settings.getFormat().setLineSeparator("\r\n");
CsvParser parser = new CsvParser(settings);
List<String[]> allRows = parser.parseAll(new FileReader(new File("path/to/file.csv")));
Disclosure: I am the author of this library. It's open-source and free (Apache V2.0 license).

Java Delete Line from File

the code below is from a reference i saw online, so there might be some similarities i'm trying to implement the code to remove an entire line based on the 1st field in this instance it is (aaaa or bbbb) the file which has a delimiter "|", but it is not working. Hope someone can advise me on this. Do i need to split the line first? or my method is wrong?
data in player.dat (e.g)
bbbb|aaaaa|cccc
aaaa|bbbbbb|cccc
Code is below
public class testcode {
public static void main(String[] args)throws IOException
{
File inputFile = new File("players.dat");
File tempFile = new File ("temp.dat");
BufferedReader read = new BufferedReader(new FileReader(inputFile));
BufferedWriter write = new BufferedWriter(new FileWriter(tempFile));
Scanner UserInput = new Scanner(System.in);
System.out.println("Please Enter Username:");
String UserIn = UserInput.nextLine();
String lineToRemove = UserIn;
String currentLine;
while((currentLine = read.readLine()) != null) {
// trim newline when comparing with lineToRemove
String trimmedLine = currentLine.trim();
if(trimmedLine.equals(lineToRemove)) continue;
write.write(currentLine + System.getProperty("line.separator"));
}
write.close();
read.close();
boolean success = tempFile.renameTo(inputFile);
}
}
Your code compares the entire line it reads from the file to the user name the user enters, but you say in your question that you actually only want to compare to the first part up to the first pipe (|). Your code doesn't do that.
What you need to do is read the line from the file, get the part of the string up to the first pipe symbol (split the string) and skip the line based on comparing the first part of the split string to the lineToRemove variable.
To make it easier, you could also add the pipe symbol to the user input and then do this:
string lineToRemove = UserIn + "|";
...
if (trimmedLine.startsWith(lineToRemove)) continue;
This spares you from splitting the string.
I'm currently not sure whether UserInput.nextLine(); returns the newline character or not. To be safe here, you could change the above to:
string lineToRemove = UserIn.trim() + "|";

Scanner reading only half the no. of lines in a file

I am trying to read a file using Scanner Object with the following code -
public void read(){
Scanner scanner = new Scanner(dataFile).useDelimiter("\n");
String line;
int i = 0;
while(scanner.hasNext()){
line = scanner.next();
i++;
}
System.out.println(i);
}
The file which I am trying to read from has 117000 lines, out of which the scanner only reads first 59550 odd lines. It does not throw any exception and simply returns.
When I change the implementation to use a BufferedReader it reads all 117000 lines -
public void read(){
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(dataFile)));
String line;
int i=0;
while((line = br.readLine())!= null){
i++;
}
System.out.println(i);
}
Can anyone explain why scanner doesn't read all lines ?
One probable reason could be that Scanner's(1KB) buffer limit is less than that of BufferedReader(8KB).
The following program works for me:
Scanner scanner = new Scanner(dataFile);
String line;
int i = 0;
while(scanner.hasNextLine()){
line = scanner.nextLine();
// System.out.println(line); // remove comment for debug
i++;
}
System.out.println(i);
scanner.close();
The changes from the original program are:
Changed hasNext() and next() to hasNextLine() and nextLine(). In this case the default delimiter is fine
Fixed a typo - system.out.println should be System.out.println
Added a comment to print line (and check if the delimiter is OK)
Added scanner.close()
It's probably something to do with the line ending, delimiter used by Scanner.
You should use the methods :
hasNextLine() and nextLine()
Can anyone explain why scanner doesn't read all lines ?
br.readLine also selects lines that end with \r (and not \n). This is one important difference with your Scanner that only reads lines with \n.

Categories