I am attempting to read from a file - my code is below:
try
{
Scanner inFile = new Scanner (new FileReader("input.txt"));
while(inFile.hasNextLine())
{
first = inFile.next();
second = inFile.next();
System.out.println("first: " + first);
System.out.println("second: " + second);
}
inFile.close();
}
catch(FileNotFoundException exception)
{
System.out.println("Unable to locate file");
}
The file text is:
Fred 10
John 13
Bob
Jill 43
Because some lines do not contain any text the program crashes. For example, this program crashes when it tries to give "second" a value in the third line - the one containing Bob.
How can I create an if value exists? Or ignore if no value?
You can use useDelimiter function and iterate the line again
while(inFile.hasNextLine())
{
Scanner sc = new Scanner(inFile.nextLine());
sc.useDelimeter(" ");
while(sc.hasNext())
System.out.println(sc.next());
}
Your program is (incorrectly) assuming that there are two values per line always. If that's not true, you'll need to consider that case. A way could be (untested):
while(inFile.hasNextLine()) {
first = inFile.next();
if (!inFile.hasNext()) {
continue; // ignore this line
}
second = inFile.next();
...
}
Unrelated to your question: you are incorrectly closing inFile. This info may come in handy.
Related
Question:
I have this set of number in a .txt document, I want to use java.util.Scanner to detect the line feed in between 123, 456, and 789, print out the numbers in between the line feeds, is there any way to do so?
1 2 3
// \n here
4 5 6
// \n here
7 8 9
Output:
456
===========================================================================
Solutions that I tried:
(1) I tried using hasNextLine() method, however, it seems like hasNextLine() will tell me are there tokens in the next line and return a boolean instead of telling me is there \n. if (scan.hasNextLine()) { \\ do something }
(2) I also tried using: (However, using such condition will say "Syntax error on token 'Invalid Character'")
Scanner scan = new Scanner(new File("test.txt"));
// create int[] nums
while (scan.hasNext()) {
String temp = scan.next();
if (temp == \n) {
// nums.add(); something like this
}
}
System.out.print(nums); // something like this
I am thinking using \n as delimiters
ps. I did google and most of the results tell me to use .hasNextLine(), but I want it to identify a line feed (\n)
Scanner scans the next element by using new-line or whitespace as a delimiter by default. To let it read the whole content use scan.useDelimiter("\\Z").
Scanner scan = new Scanner(new File("test.txt"));
scan.useDelimiter("\\Z");
final String content = scan.next(); // content: "1 2 3\r\n\r\n4 5 6"
int index = 0;
System.out.println("Index of \\n");
while (index != -1) {
index = content.indexOf("\n", index);
if (index != -1) {
System.out.println(index);
// Or do whatever you wish
index++;
}
}
Output:
Index of \n
5
7
I'm not sure I understand 100% your question. So I'm assuming your file always will have 2 lines separated by ONLY ONE new line(\n). If I'm wrong please tell it.
String charsAfterNewLine = null;
//try-catch block with resources
//Scanner need to be closed (scan.close()) after finish with it
//this kind of block will do `scan.close()` automatically
try(Scanner scan = new Scanner(new File("test.txt"))){
//consume(skip) first line
if(scan.hasNextLine()){
scan.nextLine();
}else{
throw new Exception("File is empty");
}
//get second line
if(scan.hasNextLine()){
charsAfterNewLine = scan.nextLine();
}else{
throw new Exception("Missing second line");
}
}catch(Exception e){
e.printStackTrace();
}
System.out.println("charsAfterNewLine: " + charsAfterNewLine);
If you want simple way, without try-catch:
String charsAfterNewLine = null;
//throws FileNotFoundException
Scanner scan = new Scanner(new File("test.txt"));
if(scan.hasNextLine()){
//consume(skip) first line
scan.nextLine();
if(scan.hasNextLine()){
//get second line
charsAfterNewLine = scan.nextLine();
}else{
System.out.println("Missing second line");
}
}else{
System.out.println("File is empty");
}
scan.close();
System.out.println("charsAfterNewLine: " + charsAfterNewLine);
Results(for both):
Input:
(empty file)
Output:
File is empty
charsAfterNewLine: null
-----
Input:
1 2 3 4 5 6
Output:
Missing second line
charsAfterNewLine: null
-----
Input:
1 2 3\n4 5 6
Output:
charsAfterNewLine: 4 5 6
while (scanner.hasNext()) {
String data = scanner.nextLine();
System.out.println("Data: " + data);
if (data.isEmpty()) {
System.out.println("Found it");
break;
}
}
I want to send studentGrade array to "calculate" method to calculate the average of grades but if the first line of text file is parameter, I can't. When the "if" method running, it goes back to while loop, even though two strings are equal.
I've tried to change the first line of .txt, in case of there is a problem. But the result was the same. It never does compare if the wanted person is in the first line.
static int studentNumber = 0;
static String[] studentGrade;
static String studentName = "";
static void makeList(String name) {
try(Scanner sc = new Scanner(new BufferedReader(new FileReader("C:\\Users\\User\\Desktop\\new_1.txt")))) {
boolean flag = true;
while (sc.hasNextLine()) {
flag = true;
String studentLine = sc.nextLine();
studentGrade = studentLine.split(",");
studentName = studentGrade[0];
if (studentName.equalsIgnoreCase(name)){
calculate(studentGrade);
flag = false;
break;
}
}
if (flag)
System.out.println("Couldn't found!");
}
catch (FileNotFoundException e) {
System.out.println("An error occured when the file was tried to opened.");
}
}
static void calculate(String[] a) {
int note1 = Integer.parseInt(a[1]);
int note2 = Integer.parseInt(a[2]);
int note3 = Integer.parseInt(a[3]);
double avg = Math.ceil((double)(note1 + note2 + note3) / 3);
System.out.println(a[0] + "'s average is: " + (int)avg);
}
I expect the if case would be true and sent the array to "calculate" method. It does its job except the student is in the first line of .txt file. For example if user input is Michael, it says "Couldn't found!" but if the input is John, it gives its average.
//First lines of .txt file
Michael,70,90,20
John,90,80,60
Molly,60,30,50
I created a file with the values you are giving:
Michael,70,90,20
John,90,80,60
Molly,60,30,50
And when I try your code, it seems to work fine:
makeList("Michael");
makeList("John");
makeList("Molly");
return
60
77
47
My suspicion is that you have some kind of invisible character at the very beginning of your file, and that is what makes your equality fail. I encountered this kind of issue several time when parsing XML and the parser would complain that my file doesn't start with an XML tag.
Can you try to make a brand new file with these 3 lines and try your program again on this new file?
Here is a much simpler and clearer way to do this:
try (Stream<String> lines = Files.lines("C:\\Users\\User\\Desktop\\new_1.txt")) {
Optional<String[]> studentGradesOpt =
lines.map(line -> line.split(","))
.filter(row -> row[0].equalsIgnoreCase(name))
.findFirst();
studentGradesOpt.ifPresent(grades -> calculate(grades));
if (!studentGradesOpt.isPresent()) {
System.out.println("Couldn't find student " + name);
}
}
I'm currently in an Introductory Java class at University and I'm having a bit of trouble. Last semester we started with Python and I became very acquainted with it and I would say I am proficient now in writing Python; yet Java is another story. Things are alot different. Anyway, Here is my current assignment: I need to write a class to search through a text document (passed as an argument) for a name that is inputted by the user and output whether or not the name is in the list. The first line of the text document is the amount of names in the list.
The text document:
14
Christian
Vincent
Joseph
Usman
Andrew
James
Ali
Narain
Chengjun
Marvin
Frank
Jason
Reza
David
And my code:
import java.util.*;
import java.io.*;
public class DbLookup{
public static void main(String[]args) throws IOException{
File inputDataFile = new File(args[0]);
Scanner stdin = new Scanner(System.in);
Scanner inFile = new Scanner(inputDataFile);
int length = inFile.nextInt();
String names[] = new String[length];
for(int i=0;i<length;i++){
names[i] = inFile.nextLine();
}
System.out.println("Please enter a name that you would like to search for: ");
while(stdin.hasNext()){
System.out.println("Please enter a name that you would like to search for: ");
String input = stdin.next();
for(int i = 0;i<length;i++){
if(input.equalsIgnoreCase(names[i])){
System.out.println("We found "+names[i]+" in our database!");
break;
}else{
continue;
}
}
}
}
}
I am just not getting the output I am expecting and I cannot figure out why.
Try this
You should trim() your values as they have extra spaces
if(input.trim().equalsIgnoreCase(names[i].trim()))
I have run your example it runs perfectly after using trim(), you have missed to trim()
Create a seperate scanner class to read line by line.You can use BufferedReader also.
final Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
final String str= scanner.nextLine();
if(str.contains(name)) {
// Found the input word
System.out.println("I found " +name+ " in file " +file.getName());
break;
}
}
If you use Java 8:
String[] names;
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
names = stream.skip(1).toArray(size -> new String[size]);
} catch (IOException e) {
e.printStackTrace();
}
There is a space between before and after = ...
( Backup = True )------ is a String to search(Even space is there between =)
File file = new File(
"D:\\Users\\kbaswa\\Desktop\\New folder\\MAINTENANCE-20150708.log.txt");
Scanner scanner = null;
try {
scanner = new Scanner(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// now read the file line by line...
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.next();
lineNum++;
String name="Backup = True";
if (line.contains(name)) {
System.out.println("I found "+name+ " in file " +file.getName());
break;
}
else{
System.out.println("I didnt found it");
}
}
}
Scanner.next() returns the next complete token, so it will be returning something like Backup, then = next time round the loop, then true next time.
Use Scanner.nextLine() to get the entire line in one go.
scanner.nextLine() would solve your problem.
If you want to stick with scanner.next() you can define a delimiter: scanner.useDelimiter("\n") this reads the file until it hits the delimiter and starts the next loop from there.
You need to read the file line-by-line and search for your string in every line. The code should look something like:
final Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
final String lineFromFile = scanner.nextLine();
if(lineFromFile.contains(inputString)) {
// a match!
System.out.println("Found " +inputString+ " in file ");
break;
}
}
Now to decide between Scanner or a BufferedReader to read the file, check this link. Also check this link for fast way of searching a string in file. Also keep in mind to close scanner once you are done.
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();