Java - Add all integers from file to ArrayList - java

I'm trying to read all integers from a file into an ArrayList in the #BeforeClass of a java JUnit test. For testing purposes, I am then simply trying to print all values of the arraylist to the screen. Nothing is being output however. Any input would be greatly appreciated.
public class CalcAverageTest
{
static List<Integer> intList = new ArrayList<Integer>();
#BeforeClass
public static void testPrep() {
try {
Scanner scanner = new Scanner(new File("gradebook.txt"));
while (scanner.hasNextInt()) {
intList.add(scanner.nextInt());
}
for (int i=0;i<intList.size();i++) {
System.out.println(intList.get(i));
}
} catch (IOException e) {
e.printStackTrace();
} catch (NumberFormatException ex) {
ex.printStackTrace();
}
}
}

(promoting a comment to an answer)
If gradebook.txt is an empty file, or starts with something that does not parse as an int, such as text or comments at the top of the file, then scanner.hasNextInt() will immediately return false, and intList will remain empty. The for loop will then loop over the empty list zero times, and no output will be generated, as observed.
I have some strings to skip over before the integers.
scanner.readLine() can be used to skip over comment lines before the numbers. If it is not a set number of lines that need skipping, or if there are words on the line before the numbers, we would need to see a sample of the input to advise the best strategy for finding the numbers in the input file.

You need to iterate over the file till the last line, so you will need to change the condition in the loop and use .hasNextLine() instead of .nextInt()
while (scanner.hasNextLine()) {
String currLine = scanner.nextLine();
if (currLine != null && currLine.trim().length() > 0 && currLine.matches("^[0-9]*$"))
intList.add(Integer.parseInt(currLine));
}
}
Here, we read each line and store it in currLine. Now only if it contains a numeric value it is added to the intList else it is skipped. ^[0-9]$* is a regex used to match only numeric values.
From the docs, hasNextLine()
Returns true if there is another line in the input of this scanner.
This method may block while waiting for input. The scanner does not
advance past any input.

Related

Read text and add to list

I am working on a method that takes a scanner as a parameter, and the values of the text file should be added to the doublyLinkedList. Right now the method is working fine but i have an issue where if it encounters a string in the text file, it stops. I want it in such a way that i skip over any line that has a string i tried using the nextLine() but it didnt work.
public static void addList(Scanner input, DoublyLinkedList list){
Number data=null;
if(input.hasNextLine()){
if(input.hasNextInt()){
data=input.nextInt();
list.addEnd(data);
parseScanner(input, list);
}
else if(input.hasNext()){
input.hasNext();
}
}
}
I think in.hasNext() should be input.hasNext()
I think you should use hasNextInt() method of the scanner. If this method will return false, you can just read string and then again try to read int.
if (input.hasNextInt()) {
// read int
} else {
input.nextLine(); // skip line that is not a number
}

Stop Scanner while reading Integers or String

I'm trying to read a String and then Integers or Strings using Scanner:
public class Main {
public static void main (String[] args){
String[] StringList;
Integer[] IntegerList;
ArrayList<String> auxS = new ArrayList<>();
ArrayList<Integer> auxI = new ArrayList<>();
String order; int ord=-1;
Scanner scan = new Scanner(System.in);
order = scan.nextLine();
//do something with order
while(scan.hasNextLine()){
if(scan.hasNextInt()){
auxI.add(scan.nextInt());
}
else if(!scan.nextLine().isEmpty()){
auxS.add(scan.nextLine());
}else{ //I've tried using another scan. methods to get to this point
scan.next();
break;
}
}
}
}
As you can see, I first read a String and store it in "order", then I want to keep reading until EOF or user enters "Enter" or anything else non-specific such as "write 'exit' " or something like that.
I've tried using scan.hasNext, hasNextLine, and other combinations involving the last else but none of them worked.
If the input is:
>>THIS WILL BE STORED IN ORDER<<
123
321
213
231
312
<enter>
I want it to stop when nothing has been entered as in the last line. It is important to store the Integers or Strings in their own ArrayLists, as I use it later and I need to identify the type of each entered data (that's why I use hasNextInt inside the while loop).
Generally, just don't use .nextLine(), it is confusing and rarely does what you want. If you want to read entire lines as a single item, update the scanner's delimiter; change it from the default 'any sequence of whitespace' to 'a single newline': scanner.useDelimiter("\r?\n"); will do that (run that immediately after making a scanner). To read a line, use any of the .next() methods (but not .nextLine()): Want an int? call .nextInt(). Want any string? Call .next(), etcetera.
then split up your if/elseif block. An empty line is still a string, just, an empty one:
if (scanner.hasNextInt()) {
// deal with ints
} else {
String text = scanner.next();
if (!text.isEmpty()) {
// deal with strings
} else {
// deal with a blank line
}
}
NB: Once you stop using .nextLine(), you don't have to throw out semi-random .nextLine() calls to 'clear the buffer' or whatnot. That annoyance just goes away, which is one of the many reasons why you should just forget about nextLine. Generally, for scanners, either use only .nextLine(), or don't ever use .nextLine(), and things work out much better.

Find Specific number in file

Hello I am trying to loop a file in java and output only string whose year has 2000 in it.
for some reason when I do .trim().compare(year) it still returns all of the string. I have no idea why
example of string in file are
20/04/1999-303009
13/04/2000-2799
06/10/1999-123
out of these 3 for example I want to get only 13/04/2000-2799 (note the file is huge)
Here is my code I came up with so far:
public static void main(String[] args) throws IOException {
//Initiating variables
String filedir =("c://test.txt");
ArrayList<String> list = new ArrayList<String>();
String year = "2000";
try (Scanner scanner = new Scanner(new File(filedir))) {
while (scanner.hasNextLine()){
// String[] parts = scanner.next().split("-");
if (scanner.nextLine().trim().contains(year)) {
System.out.println(scanner.nextLine());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
You are using scanner.nextLine() two times. That's an error. Call it's only once per iteration and assign the result to String value for usage.
You're calling scanner.nextLine() twice, which means that once you found a matching line, you are actually printing the next one.
the problem in your code is in the while block:
while(scanner.hasNextLine()){
//This first call returns 13/04/2000-2799
if(scanner.nextLine().trim().contains(year)){//This line finds matching value
//But this line prints the next line
System.out.println(scanner.nextLine());//this call returns 06/10/1999-123
}
}
What you could do is store the value you need in a variable and if it matches the year then you print it:
while(scanner.hasNextLine()){
//You store the value
String value = scanner.nextLine().trim();
//See if it matches the year
if(value.contains(year)){
//Print it in case it matches
System.out.println(value);
}
}
Hope this helps.

How to get a Scanner to ignore words between a certain pattern

I want to read input from a file using a scanner, but I want the scanner to ignore everything inside (* ....... *). How do I do this? I'm taking integers and adding them to an array list, but if there are integers inside the text I want to ignore it adds those too.
public ArrayList<Integer> readNumbers(Scanner sc)
{
// TODO Implement readNumbers
ArrayList<Integer> list = new ArrayList<Integer>();
while(sc.hasNext())
{
try
{
String temp = sc.next();
list.add(Integer.parseInt(temp));
}
catch(Exception e)
{
}
}
return list;
}
Here's an example line of the text file
(* 21 Alabama Population in 2013 *) 4802740
I would add 21 and 4802740 to my array list.
I thought about using
sc.usedelimiter("(");
sc.usedelimiter(")");
But I just can't seem to get it to work.
Thanks!
It seems that you may be looking for something like
sc.useDelimiter("\\(\\*[^*]*\\*\\)|\\s+");
This regular expression \\(\\*[^*]*\\*\\) represents part which
\\(\\* - starts with (*,
\\*\\) - ends with *)
[^*]* - and have zero or more non * characters inside.
I also added |\\s+ to allow one or more spaces be delimiter (this delimiter is used by scanners by default).
BTW using try-catch as main part of control flow is generally considered as wrong. Instead you should change your code to something like
while (sc.hasNext()) {
if(sc.hasNextInt()) {
list.add(sc.nextInt());
} else {
//consume data you are not interested in
//so Scanner could move on to next tokens
sc.next();
}
}
Skip the "(* string *)" before reading next int:
try
{
try {
sc.skip("\\s*\\(\\*[^*]*\\*\\)");
} catch (NoSuchElementException e) {
}
String temp = sc.next();
list.add(Integer.parseInt(temp));
} catch (Exception e) {
}

Why does my while loop needs this line of code to run?

I just completed an application which prompts the user for a text File input IO but I have something to clarify as the final part, While loop I actually managed to refer it to a tutorial on google. In this loop, there is a if-else statement and for the else part I don't understand why is it necessary.
Here's my code:
import java.io.*;
import java.util.*;
class FileReadingExercise2 {
public static void main(String[] args) {
Scanner userInput = new Scanner(System.in);
Scanner fileInput = null;
do {
try {
System.out.println("Please enter the name of a file or type QUIT to finish");
String a = userInput.nextLine();
if (a.equals("QUIT")) { // if user inputs QUIT then stop application
System.exit(0);
}
fileInput = new Scanner(new File(a)); // the file contains text and integers
} catch (FileNotFoundException e) {
System.out.println("Error - File not found");
}
} while (fileInput == null);
int sum = 0;
while (fileInput.hasNext()) // continues loop as long as there is a next token
{
if (fileInput.hasNextInt()) // if there is an int on the next token
{
sum += fileInput.nextInt(); // then adds the int to the sum
} else {
fileInput.next(); // else go to the next token
}
}
System.out.println(sum);
fileInput.close();
}
}
As you can see, as long as the fileInput Scanner has a next token to look up to then operate the if else statement. If fileInput has a next Int then adds it up to the sum variable. So from what I think is that this will be sufficient. Once fileInput has no more token to read, it shall get out of the while loop isn't it? Why does it has still go onto the next token? I'm confused. Please advise thanks! ;)
Why does it has still go onto the next token?
That is because when nextInt() is executed it will consume the int number within the file but within it, it has a newLine character that needs to be consume and that is when next is executed to consume that newLine after the int number.
sample file content:
1
what actually in there is 1 character and newline \n character
In this loop, there is a if-else statement and for the else part I don't understand
why is it necessary.
fileInput.hasNexInt() method returns true if int value found and than it performs adding operation. if next value is not int type than else part will perform where fileInput.next() will return next value(pointer will points after that value), performs nothing means escaping next value(which can be any type except int-type). Again if condition will check for int.

Categories

Resources