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.
Related
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.
try {
Scanner sc = new Scanner(new File("testing.txt"));
while (sc.hasNextInt()){
int i = sc.nextInt();
//timing.add(i);
System.out.println(i);
}
sc.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}
The text file does have int and strings in it. I can get it to print words from the text file, but not the numbers.
The text file includes the following:
Michael 3000 7000 Bilbo I like the number 2000 do you? No,
I like 9000
Your first value ("Michael") isn't an integer, therefore it never gets inside of the body of the loop.
Perhaps you want to change the code to loop until it reaches the end of the file, reading and printing integers, but consuming (without printing) non-integer values. So something like this:
import java.util.*;
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(new File("test.txt"));
while (sc.hasNext()) {
if (sc.hasNextInt()) {
System.out.println(sc.nextInt());
} else {
// Just consume the next token
sc.next();
}
}
sc.close();
}
}
You never enter your while loop. Because the first input Michael is not a number.
A solution would be to take .next() and use a try-catch to parse an int out of it:
while (sc.hasNext() {
String input = sc.next();
try {
int printInt = Integer.parseInt(input);
System.out.println(printInt);
} catch () {}
The problem is that hasNextInt will return false for your initial string token ("Michael"), hence your loop will never execute any statement within.
You can parse every line and infer whether the tokens are convertible to integer types instead:
while (sc.hasNext()) {
try {
System.out.println(Integer.parseInt(sc.next()));
} catch (NumberFormatException nfe) {
// nope
}
}
Will print...
3000
7000
2000
9000
The issue is that you have a mix of words and numbers. When you call sc.hasNextInt(), it checks against "Michael", which isn't an integer, so it returns false and never executes. In this case, you can read the entire line, and split it on spaces. Then check if each word is an integer using regex. You can also check by using a try...catch block and attempting to parse an integer inside of that block.
Scanner sc = new Scanner(new File("StackTxtFiles/text.txt"));
while(sc.hasNextLine()){
String [] lineSplitArray = sc.nextLine().split(" ");
for(String wordInLine : lineSplitArray){
if(wordInLine.matches("-?\\d+(\\.\\d+)?")){
System.out.println(Integer.valueOf(wordInLine));
}
}
}
sc.close();
The problem is you are checking for an int first. There is not an int first so it will exit your while loop without doing anything:
while (sc.hasNextInt()){
Michael 3000
Michael is not an int it is a String so there is no hasNextInt() there is a hasNext() and hasNextLine()...
What you can do is:
while (sc.hasNext()){
try
{
System.out.println(Integer.parseInt(sc.next());
}catch(Exception e){}
}
I do not know how to take the integer and ignore the strings from the file using scanner. This is what I have so far. I need to know how to read the file token by token. Yes, this is a homework problem. Thank you so much.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ClientMergeAndSort{
public static void main(String[] args){
int length = 13;
try{
Scanner input = new Scanner(System.in);
System.out.print("Enter the file name with extention : ");
File file = new File(input.nextLine());
input = new Scanner(file);
while (!input.hasNextInt()) {
input.next();
}
int[] arraylist = new int[length];
for(int i =0; i < length; i++){
length++;
arraylist[i] = input.nextInt();
System.out.print(arraylist[i] + " ");
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Take a look at the API for what you're doing.
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#hasNextInt()
Specifically, Scanner.hasNextInt().
"Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input."
So, your code:
while (!input.hasNextInt()) {
input.next();
}
That's going to look and see if input hasNextInt().
So if the next token - one character - is an int, it's false, and skips that loop.
If the next token isn't an int, it goes into the loop... and iterates to the next character.
That's going to either:
- find the first number in the input, and stop.
- go to the end of the input, not find any numbers, and probably hits an IllegalStateException when you try to keep going.
Write down in words what you want to do here.
Use the API docs to figure out how the hell to tell the computer that. :) Get one bit at a time right; this has several different parts, and the first one doesn't work yet.
Example: just get it to read a file, and display each line first. That lets you do debugging; it lets you build one thing at a time, and once you know that thing works, you build one more part on it.
Read the file first. Then display it as you read it, so you know it works.
Then worry about if it has numbers or not.
A easy way to do this is read all the data from file in a way that you prefer (line by line for example) and if you need to take tokens, you can use split function (String.split see Java doc) or StringTokenizer for each line of String that you are reading using a loop, in order to create tokens with a specific delimiter (a space for example) so now you have the tokens and you can do something that you need with them, hope you can resolve, if you have question you can ask.
Have a nice programming.
import static java.nio.file.Files.readAllBytes;
import static java.nio.file.Paths.get;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String args[]) throws IOException {
String newStr=new String(readAllBytes(get("data.txt")));
Pattern p = Pattern.compile("-?\\d+");
Matcher m = p.matcher(newStr);
while (m.find()) {
System.out.println("- "+m.group());
}
}
}
This code fill read the file and then using the regular expression you can get only Integer values.
Note: This code works in Java 8
I Think This will work for you requirement.
Before reading the data from the file initially,try to write some content to the file by using scanner and filewriter then try to execute the below code snippet.
File file = new File(your filepath);
List<Integer> list = new ArrayList<Integer>();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String str =null;
while(true) {
str = bufferedReader.readLine();
if(str!=null) {
System.out.println(str);
char[] chars = str.toCharArray();
String finalInt = "";
for(int i=0;i<chars.length;i++) {
if(Character.isDigit(chars[i])) {
finalInt=finalInt+chars[i];
}
}
list.add(Integer.parseInt(finalInt));
System.out.println(list.size());
System.out.println(list);
} else {
break;
}
}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
The final println statement will display all the integer in your file line by line.
Thanks
I am writing a program that reads a text file passed as an argument to the main method and extracts all the unique words from the file and prints them in the console one per line. I am having trouble passing the tokens to a string array while each line is being read from the scanner:
There's a couple things I see that are wrong or could be written in a more efficient manner:
1)tokens is initialized to 100. This an obvious constraint, I thought about using something like a dynamic array like arrayList or vector but ultimately decided to use simple string array and simply expand the array (i.e. create a new array double the size of the original array, by writing some type of conditional statement that will determine if the tokens is filled up with max elements but scanner still has more lines.
2)I am not sure if simply passing input.hasNextLine() as the test statement in the for loop makes sense. I basically want to loop as long as input has reached EOF
3) I want the regex expression in split to catch all punctuation, whitespaces, and digits, I'm not 100% sure if it's written correctly
4) The line in question is tokens[index] = token[index], I'm not sure this correct. I want the tokens from each line being to be added to tokens.
public static void main(String[] arg) throws FileNotFoundException {
File textFile = new File(arg[0]);
String[] tokens = new String[100];
try {
Scanner input = new Scanner(textFile);
for (int index = 0; input.hasNextLine(); index++) {
String[] token = input.nextLine().split("[.,;']+\\d +\\s");
tokens[index] = token[index];
}
for (String token : tokens) {
System.out.println(token);
}
input.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
There are several errors in the code, I'll try to cover all of them:
change tokens to be an ArrayList, there is no reason not to
you need two iterations: a) lines in the file and b) tokens in the line
the regex is really specific of what you have between tokens (punctuations + one digit + spaces + other space)
public static void main(String[] arg) throws FileNotFoundException {
File textFile = new File(arg[0]);
ArrayList<String> tokens = new ArrayList<String>();
try {
Scanner input = new Scanner(textFile);
while (input.hasNextLine()) {
String[] lineTokens = input.nextLine().split("[,;:\"\\.\\s]+");
for (String token : lineTokens) {
tokens.add(token);
}
}
for (String token : tokens) {
System.out.println(token);
}
input.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
The regex can be improved but it depends on your data anyway so I can't know all the cases you need to handle.
I am making a method that prints lines in a file which contain a certain word. If the parameter is an empty String, it is supposed to print the entire file.
I've gotten the first part to work. Everything in the "else" statement works great; it scans each line and prints the lines that contain the word in the parameter.
BUT I can't get it to print the whole file when an empty String ("") is entered as the parameter "word". I'm not sure why this is.
public void printLinesWhichContain(String word) {
while (this.reader.hasNextLine()) {
String line = this.reader.nextLine();
if (word.isEmpty()) {
System.out.println(line);
} else {
Scanner lineReader = new Scanner(line);
while (lineReader.hasNext()) {
if (lineReader.next().equals(word)) {
System.out.println(line);
}
}
}
}
}
Once you have the line in String format, you can use the indexOf method to get the index of the word.
I wouldn't create a Scanner for each and every line.
I mean you might want to change the else part as follows.
int indexOfWord = line.indexOf(word);
if (indexOfWord >= 0)
{
System.out.println(line);
}