Java - Reading first word of text file - java

I am having trouble reading the first word of a text file. If the first word equals 'Circle' I want to create a new Circle object in my array.
FileInputStream fileIn = new FileInputStream("shapeFile.txt");
Scanner scan = new Scanner(fileIn);
while(scan.hasNextLine()) {
String shape = scan.next();
if(shape.equals("Circle")) {
myShapes.addShape(new Circle(scan.nextInt(), scan.nextInt(), scan.nextInt(), Color.RED));
}
}
I am getting the following error for the above code, pointing to the line String shape = scan.next();
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at shapes.ShapeManagement.main(ShapeManagement.java:151)
Java Result: 1
If anyone could help me resolve this I would be most grateful.

The reason your likely getting this exception is because scan.hasNextLine() can return true even if there are no tokens on that line. If you call scan.next() when there are no tokens after the marker, you will get the java.util.NoSuchElementException you are seeing.
So, swap out scan.hasNextLine() for scan.hasNext().
Alternatively you could swap out scan.next() for scan.nextLine() and then check whether the first word in that line was the one you are looking for. This could potentially be faster for files with large numbers of lines.
I hope this helps.
Link to the Scanner API for reference.

You may want to modify the code as follows:
FileInputStream fileIn = new FileInputStream("shapeFile.txt");
Scanner scan = new Scanner(fileIn);
int[] var1 = new int[3];
while(scan.hasNext()) {
String shape = scan.next();
if(shape.equals("Circle")) {
for(int i = 0; i < 3;i++) {
if(scan.hasNextInt()) {
var1[i] = scan.nextInt();
} else {
break;
}
}
myShapes.addShape(new Circle(var1[0], var1[1], var1[2], Color.RED));
}
}

Related

Counting the number of items in a file using java

I have a text file:
2|BATH BENCH|19.00
20|ORANGE BELL|1.42
04|BOILER ONION|1.78
I need to get the number of items which is 3 here using JAVA. This is my code:
int Flag=0;
File file = new File("/Users/a0r01ox/Documents/costl-tablet-automation/src/ItemUPC/ItemUPC.txt");
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
Flag=Flag+1;
}
It is going in an infinite loop.
Can someone please help? Thank you.
You must get the next line to avoid an endless loop.
int Flag = 0;
File file = new File("/Users/a0r01ox/Documents/costl-tablet-automation/src/ItemUPC/ItemUPC.txt");
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
sc.nextLine();
Flag++;
}
while (sc.hasNextLine()) {
Flag=Flag+1;
String line = sc.nextLine(); //Do whatever with line
}
In the code you have written
int Flag=0;
File file = new File("/Users/a0r01ox/Documents/costl-tablet-automation/src/ItemUPC/ItemUPC.txt");
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) { // this line is just checking whether there is next line or not.
Flag=Flag+1;
}
When you write while (sc.hasNextLine()){} it check whether there is nextLine or not.
eg line 1 : abcdefg
line 2: hijklmnop
here your code will just be on line 1 and keep telling you that yes there is a nextLine.
Whereas when you write
while(sc.hasNextLine()){
sc.nextLine();
Flag++;
}
Scanner will read the line 1 and then because of sc.nextLine() it will go to line 2 and then when sc.hasNextLine() is checked it gives false.

Handling string out of range exception

I am doing a very basic loop through a file. The file contains a number of entries, however, it seems to break after the 3rd loop which definately contains more than 25 characters. The simple loop is as follows:
public static void organiseFile() throws FileNotFoundException {
ArrayList<String> lines = new ArrayList<>();
String directory = "C:\\Users\\hussainm\\Desktop\\Files\\ex1";
Scanner fileIn = new Scanner(new File(directory + "_temp.txt"));
PrintWriter out = new PrintWriter(directory + "_ordered.txt");
while (fileIn.hasNextLine() == true) {
if (!fileIn.nextLine().isEmpty()) {
lines.add(fileIn.nextLine());
String test = fileIn.nextLine().substring(12, 25);
System.out.println(test);
}
}
I am not sure what the issue is, but it keeps throwing:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 25 at java.lang.String.substring(Unknown
Source) at
fedOrganiser.fedOrganiser.organiseFile(fedOrganiser.java:41) at
fedOrganiser.fedOrganiser.main(fedOrganiser.java:31)
Not sure what its issue is.
File is as follows:
https://www.dropbox.com/s/69h1f8u387zikbp/ex1_temp.txt?dl=0
Every call to nextLine() reads the next line from the stream. It is nextLine(), not hasNextLine(), which advances the stream one line's worth of text. You are reading 3 lines per loop.
When calling nextLine for the first time in a loop, assign it to a variable and refer to that variable for the rest of the loop.
String line = fileIn.nextLine();
if (!line.isEmpty()) {
lines.add(line);
String test = line.substring(12, 25);
System.out.println(test);
}
Incidentally, there is no need to compare a boolean such as what is returned by hasNextLine() to true. Just use the boolean itself, e.g.:
while (fileIn.hasNextLine()) {
You're assuming every line has at least 25 characters in it with the line:
String test = fileIn.nextLine().substring(12, 25);
I'm guessing you have some lines that are shorter or blank.
You'd check String length() before doing substrings.
The call to scanner.nextLine() advances to the next line. You should do it like this, if you are sure that every line has at least 25 characters:
public static void organiseFile() throws FileNotFoundException {
ArrayList<String> lines = new ArrayList<>();
String directory = "C:\\Users\\hussainm\\Desktop\\Files\\ex1";
Scanner fileIn = new Scanner(new File(directory + "_temp.txt"));
PrintWriter out = new PrintWriter(directory + "_ordered.txt");
while (fileIn.hasNextLine()) {
String line = fileIn.nextLine();
if (!line.isEmpty()) {
lines.add(line);
String test = line.substring(12, 25);
System.out.println(test);
}
}
...
}
What I do not understand is what you want to test with line.isEmpty() because this will be always true as long as there are lines. Even a seemingly empty line contains at least a line break.
The exception will be thrown if the line you are parsing is of less than 25 chars long.
Notes
Not sure if your intent is to parse every 3 lines, but
fileIn.nextLine() appear three time. So you are missing one line out of three.
See doc:
Advances this scanner past the current line and returns the input that
was skipped.
Maybe this is what you are trying to do:
Scanner in = null;
PrintWriter out = null;
try {
URL url = this.getClass().getResource("/test_in.txt");
File file = new File(url.getFile());
ArrayList<String> lines = new ArrayList<>();
in = new Scanner(file);
out = new PrintWriter("/test_out.txt");
int lineNumber = 0;
while (in.hasNextLine()) {
String line = in.nextLine();
lineNumber++;
if (line != null && line.trim().length() > 0) {
lines.add(line);
String test = line.substring(12, line.length()<25?line.length():25);
System.out.println(String.format("line# %d: \t\"%s\"", lineNumber, test));
}
}
System.out.println(String.format("last line number: %d", lineNumber));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
in.close();
out.close();
}
EDIT: For the completeness

removeAll operation on arraylist makes program hang

I'm trying to read in from two files and store them in two separate arraylists. The files consist of words which are either alone on a line or multiple words on a line separated by commas.
I read each file with the following code (not complete):
ArrayList<String> temp = new ArrayList<>();
FileInputStream fis;
fis = new FileInputStream(fileName);
Scanner scan = new Scanner(fis);
while (scan.hasNextLine()) {
Scanner input = new Scanner(scan.nextLine());
input.useDelimiter(",");
while (scan.hasNext()) {
String md5 = scan.next();
temp.add(md5);
}
}
scan.close();
return temp;
Each file contains almost 1 million words (I don't know the exact number), so I'm not entirely sure that the above code works correctly - but it seems to.
I now want to find out how many words are exclusive to the first file/arraylist. To do so I planned on using list1.removeAll(list2) and then checking the size of list1 - but for some reason this is not working. The code:
public static ArrayList differentWords(String fileName1, String fileName2) {
ArrayList<String> file1 = readFile(fileName1);
ArrayList<String> file2 = readFile(fileName2);
file1.removeAll(file2);
return file1;
}
My main method contains a few different calls and everything works fine until I reach the above code, which just causes the program to hang (in netbeans it's just "running").
Any idea why this is happening?
You are not using input in
while (scan.hasNextLine()) {
Scanner input = new Scanner(scan.nextLine());
input.useDelimiter(",");
while (scan.hasNext()) {
String md5 = scan.next();
temp.add(md5);
}
}
I think you meant to do this:
while (scan.hasNextLine()) {
Scanner input = new Scanner(scan.nextLine());
input.useDelimiter(",");
while (input.hasNext()) {
String md5 = input.next();
temp.add(md5);
}
}
but that said you should look into String#split() that will probably save you some time:
while (scan.hasNextLine()) {
String line = scan.nextLine();
String[] tokens = line.split(",");
for (String token: tokens) {
temp.add(token);
}
}
try this :
for(String s1 : file1){
for(String s2 : file2){
if(s1.equals(s2)){file1.remove(s1))}
}
}

Scanner to reset pointer at previous line

My problem could be solved if Scanner class had previous() method on it. I am asking this question to know if there are any methods to achieve this functionality.
Input:
a file with contents like
a,1
a,2
a,3
b,1
c,1
c,2
c,3
c,4
d,1
d,2
d,3
e,1
f,1
I need to create a list of all lines that has same alphabet.
try {
Scanner scanner = new Scanner(new File(fileName));
List<String> procList = null;
String line =null;
while (scanner.hasNextLine()){
line = scanner.nextLine();
System.out.println(line);
String[] sParts = line.split(",");
procList = new ArrayList<String>();
procList.add(line);
boolean isSamealpha = true;
while(isSamealpha){
String s1 = scanner.nextLine();
if (s1.contains(sParts[0])){
procList.add(s1);
}else{
isSamealpha = false;
System.out.println(procList);
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
I get output like
a,1
[a,1, a,2, a,3]
c,1
[c,1, c,2, c,3, c,4]
d,2
[d,2, d,3]
f,1
[f,1]
As you can see it missed list for b and e. If I has scanner.previous() method, I would have put it in else of second while loop. Because there is no previous method, I am stuck.
Please let me know if there are any methods I can use. I can't use FileUtils.readLines() because its a 3GB file and I don't want to use my java memory to store all the file.
I would suggest reconsidering your algorithm instead. You are missing tokens because your algorithm involves reading ahead to determine when the sequence has broken, yet you aren't collecting that next line of input into the same structures that you are placing "duplicate" entries.
You can solve this without needing to read backwards. If you know that the input is always sorted, just read line by line and keep a reference to the last line (to compare with the current one).
Below is some sample code that should help. (I only typed this; I did no checking.)
Scanner scanner = new Scanner(new File(fileName));
List<String> procList = null;
String line = null;
String previousAlpha = null;
while (scanner.hasNextLine()){
line = scanner.nextLine();
if (previousAlpha == null) {
// very first line in the file
procList = new ArrayList<String>();
procList.add(line);
System.out.println(line);
previousAlpha = line.split(",")[0];
}
else if (line.contains(previousAlpha)) {
// same letter as before
procList.add(line);
}
else {
// new letter, but not the very first
// line
System.out.println(procList);
procList = new ArrayList<String>();
procList.add(line);
System.out.println(line);
previousAlpha = line.split(",")[0];
}
}

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

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

Categories