Can't compare the first line of .txt file with a string - java

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

Related

Read data from file and convert to key value pair

I have the below integers in File :
758 29
206 58
122 89
I have to read these integers in an integer array and then need to store the values in key value pair. Then print the output as :
Position 29 has been initialized to value 758.
Position 89 has been initialized to value 122.
I have tried as of now :
private static Scanner readFile() {
/*
* Your program will prompt for the name of an input file and the read
* and process the data contained in this file. You will use three
* integer arrays, data[], forward[] and backward[] each containing 100
* elements
*/
int data[] = new int[100];
int forward[] = new int[100];
int backward[] = new int[100];
System.out.print("Please enter File Name : ");
#SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
String filename = scanner.nextLine();
File inputFile = new File(filename);
Scanner linReader = null;
try {
linReader = new Scanner(new File(filename));
while (linReader.hasNext()) {
String intStringSplit = linReader.nextLine();
String[] line = intStringSplit.split("\t",-1);
data = new int[line.length];
for (int i = 0; i < data.length; i++) {
data[i] = Integer.parseInt(line[i]);
}
System.out.println(data);
}
linReader.close();
} catch (Exception e) {
System.out.println("File Not Found");
}
return linReader;
}
I am not able to figure out how to get the key and value from the read data.
When posting information related to your question it is very important that you provide the data (in file for example) exactly as it is intended in reality so that we can make a more positive determination as to why you are experiencing difficulty with your code.
What you show as an in file data example indicates that each file line (which contains actual data) consists of two specific integer values. The first value being the initialization value and the second being the position value.
There also appears to be a blank line after ever line which contains actual data. This really doesn't matter since the code provided below has a code line to take care of such a thing but it could be the reason as to why you may be having difficulty.
To me, it looks like the delimiter used to separate the two integer values in each file line is indeed a whitespace as #csm_dev has already mentioned within his/her comment but you claim you tried this in your String.split() method and determined it is not a whitespace. If this is truly the case then it will be up to you to determine exactly what that delimiter might be. We couldn't possibly tell you since we don't have access to the real file.
You declare a File object within your provided code but yet nowhere do you utilize it. You may as well delete it since all it's doing is sucking up oxygen as far as I'm concerned.
When using try/catch it's always good practice to catch the proper exceptions which in this case is: IOException. It doesn't hurt to also display the stack trace as well upon an exception since it can solve a lot of your coding problems should an exception occur.
This code should work:
private static Scanner readFile() {
/*
* Your program will prompt for the name of an input file and the read
* and process the data contained in this file. You will use three
* integer arrays, data[], forward[] and backward[] each containing 100
* elements
*/
int data[] = new int[100];
int forward[] = new int[100];
int backward[] = new int[100];
System.out.print("Please enter File Name : ");
Scanner scanner = new Scanner(System.in);
String filename = scanner.nextLine();
File inputFile = new File(filename); // why do you have this. It's doing nothing.
Scanner linReader = null;
try {
linReader = new Scanner(new File(filename));
while (linReader.hasNext()) {
String intStringSplit = linReader.nextLine();
// If the file line is blank then just
// continue to the next file line.
if (intStringSplit.trim().equals("")) { continue; }
// Assuming at least one whitespace is used as
// the data delimiter but what the heck, we'll
// use a regular expression within the split()
// method to handle any number of spaces between
// the integer values.
String[] line = intStringSplit.split("\\s+");
data = new int[line.length];
for (int i = 0; i < line.length; i++) {
data[i] = Integer.parseInt(line[i]);
}
System.out.println("Position " + data[1] +
" has been initialized to value " +
data[0] + ".");
// do whatever else you need to do with the
// data array before reading in the next file
// line......................................
}
linReader.close();
}
catch (IOException ex) {
System.out.println("File Not Found");
ex.printStackTrace();
}
return linReader;
}

Count the number of times a set of characters appear in a file without BufferedReader

I am trying to count the number of times a string appears in a file. I want to find the number of times that "A, E, I, O, U" appears exactly in that order. Here is the text file:
AEIOU aeiou baeiboeu bbbaaaaaa beaeiou caeuoi ajejijoju aeioo
aeiOu ma me mi mo mu
take it OUT!
I want the method to then return how many times it is in the file. Any idea's on how I could go about doing this? The catch is I want to do this without using BufferedReader. I can simply just read the file using Scanner. Is there a way to do this?
I edited this and added the code I have so far. I don't think I am even close. I am pretty sure I need to use some nested loops to make this happen.
import java.util.*;
import java.io.*;
public class AEIOUCounter
{
public static final String DELIM = "\t";
public static void main(String[] args)
{
File filename = new File("aeiou.txt");
try
{
Scanner fileScanner = new Scanner(new File(filename));
while(fileScanner.hasNextLine())
{
System.out.println(fileScanner.nextLine());
}
}
catch(IOException e)
{
System.out.println(e);
}
catch(Exception e)
{
System.out.println(e);
}
fileScanner.close();
}
}
What you are doing now, is printing all the lines in the file.
fileScanner.hasNextLine()
fileScanner.nextLine()
But what you are looking for is filtering out separate words in the file:
Path path = Paths.get("/path/to/file");
Scanner sc = new Scanner(path);
int counter = 0;
while (sc.hasNext()) {
String word = sc.next();
if (word.equalsIgnoreCase("AEIOU")) {
counter += 1;
}
}
System.out.print("Number of words: " + counter);
Smurf's answer is great. It's worth mentioning that if you're using Java 8, you can avoid using a Scanner at all, and do this in a single expression:
long count = Files.lines(Paths.get("aeiou.txt"))
.flatMap(s -> Arrays.stream(s.split(" ")))
.filter(s -> s.equalsIgnoreCase("aeiou"))
.count();

Scanner reading "\n" or Enter/Return key

So, I'm trying to set up a simple config for a project. The goal here is to read certain values from a file and, if the file does not exist, to write said file. Currently, the creation of the file works fine, but my Scanner is acting a bit funny. When I reach the code
case "resolution": resolution = readConfig.next();
it makes the value of resolution "1024x768\nvsync" whereas it should only be "1024x768". If it were working as I planned, then the next value for
readingConfig = readConfig.next();
at the beginning of my while loop would be "vsync", which my switch statement would then catch and continue editing the values to those of the file.
Why is my Scanner picking up on the "\n" that is the 'enter' to the next line in the text document?
public static void main(String[] args) {
int musicVol = 0;
int soundVol = 0;
String resolution = null;
boolean vsync = false;
Scanner readConfig;
String readingConfig;
File configFile = new File(gameDir + "\\config.txt");
if (configFile.exists() != true) {
try {
configFile.createNewFile();
PrintWriter writer = new PrintWriter(gameDir + "\\config.txt");
writer.write("resolution = 1024x768 \n vsync = true \n music = 100 \n sound = 100");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
readConfig = new Scanner(configFile);
readConfig.useDelimiter(" = ");
while (readConfig.hasNext()) {
readingConfig = readConfig.next();
switch (readingConfig) {
case "resolution":
resolution = readConfig.next();
break;
case "vsync":
vsync = readConfig.nextBoolean();
break;
case "music":
musicVol = readConfig.nextInt();
break;
case "sound":
soundVol = readConfig.nextInt();
break;
}
}
readConfig.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Instead of using .hasNext and .next(), you will have to use .hasNextLine() and .nextLine(). I would write this as a comment, but do not have enought rep to comment yet.
You are using next() which will not delimit your lines, try using nextLine() instead:
String nextLine() Advances this scanner past the current line and
returns the input that was skipped.
I'd suggest not using the delimiter, and get the whole line instead as a string, and then split the string to the parts you want.
Something like
String nextLine = readConfig.nextLine();
String[] split = nextLine.split(" = ");
String resolution = split[1]; // just an example
...
Aha, solved!
What this does is pull the entire text file into a String (using Scanner.nextLine() removes the '\n') and then adds the " = " at the end of each line instead. Thus, when the Scanner runs back over the String for the switch, it will already be ignoring the " = " and pull the desired information from the String.
String config = "";
try {
readConfig = new Scanner(configFile);
while (readConfig.hasNext()) {
config += readConfig.nextLine() + " = ";
readConfig = new Scanner(config);
readConfig.useDelimiter(" = ");

java.util.NoSuchElementException error, looked for possible reasons, still can't fix it

I am getting java.util.NoSuchElementException error. We get this error for the following reasons.
If we don't check if the file has next line before reading it,
then it throws exception after reading last line since it is trying
to read a line which doesn't exist.
Format of the file is messed up
I think that the format of the file I m using is correct and I am also checking for next line before reading it but I am still getting the error.
When I debug it using print statement, it prints all the line and throws java.util.NoSuchElementException error after reading last line.
Please help me out
Here is the code :
public static void InterpretMessageFromFile() throws FileNotFoundException{
File inputfile = new File("filepath");
Scanner reader = new Scanner(inputfile);
try {
while (reader.hasNextLine()) {
String MessageType = reader.next();
int IsAdd = MessageType.compareToIgnoreCase("A");
int IsCancel = MessageType.compareToIgnoreCase("X");
int IsDelete = MessageType.compareToIgnoreCase("D");
int IsExecute = MessageType.compareToIgnoreCase("E");
int IsReplace = MessageType.compareToIgnoreCase("U");
//if the type of order is add order to existing Order Book
if (IsAdd == 0) {
String retrieve_ts = reader.next();
int ts = Integer.parseInt(retrieve_ts);
String retrieve_id = reader.next();
int id = Integer.parseInt(retrieve_id);
String or_side = reader.next();
String retrieve_share = reader.next();
int share = Integer.parseInt(retrieve_share);
String retrieve_price = reader.next();
int price = Integer.parseInt(retrieve_price);
System.out.println("Add Order : Id is " + id );
AddOrderToExistingBook.AddNewOrder(id, ts, or_side, share, price);
}
//if it is cancel order
if (IsCancel == 0){
String retrieve_ts = reader.next();
int ts = Integer.parseInt(retrieve_ts);
String retrieve_id = reader.next();
int id = Integer.parseInt(retrieve_id);
System.out.println("Cancel Order : Id is " + id + " time stamp is : " + ts );
CancelOrder.CancelPartOfOrder(id, ts);
}
}
}
}
finally {
reader.close();
}
}
Exception (copied from comments):
Exception in thread "main" java.util.NoSuchElementException at
java.util.Scanner.throwFor(Scanner.java:907) at
java.util.Scanner.next(Scanner.java:1416) at
OrderBook.InterpretOrderBookUpdateMessage.InterpretMessageFromFile(InterpretOrde‌​rBookUpdateMessage.java:20)
at OrderBook.MainMethod.main(MainMethod.java:50)
you are trying to consume a token that is not there.
you do a number of next() calls without checking if there is next.
in your case, I suspect a newline at the end of your file gives you an empty line as input.
the scanner will see a new line, but as it doesn't contain tokens, calling "next()" will cause an error.
the same would happen if you have empty lines between blocks in your file.
one thing you can use is:
public boolean hasNext(String pattern)
instead of
next()
this will let you do a lookahead without consuming a token.
so instead of:
String MessageType = reader.next();
int IsAdd = MessageType.compareToIgnoreCase("A");
int IsCancel = MessageType.compareToIgnoreCase("X");
// .... left out other classes
//if the type of order is add order to existing Order Book
if (IsAdd == 0){
// .. do stuff
}
you can do something like:
if (reader.hasNext("A") {
reader.next(); // consume A
int ts = reader.nextInt(); // get id
// ... etcetera
} else if (reader.hasNext("X") {
}
I would also recommend you use nextInt() instead of nextString and then calling parseInt
One other thing: you can even make your code better to read by doing:
if (reader.hasNext("A") {
handleAddition(reader);
}
and then later on define a method that only handles this case.
your main method will look like:
try
{
while (reader.hasNextLine())
{
if (reader.hasNext("A")) {
handleAdd(reader);
} else if (reader.hasNext("X")) {
handleCancel(reader);
} else if (reader.hasNext("D")) {
handleDelete(reader);
} else if (reader.hasNext("E")) {
handleExecute(reader);
} else if (reader.hasNext("R")) {
handleReplace(reader);
} else {
// unexpected token. pretty sure this is the case that triggers your exeception.
// basically log as info and ignore.
reader.nextLine();
}
}
}
finally
{
reader.close();
}
Now your method is nice and short, and all the specific actions are taken in methods with their own name.
the only thing I'm not 100% about if it it's good practice to consume A, X, R, etc... inside the main loop, or the actual handler method. I prefer to consume inside the method personally.
hope it helps.

Reading a string with new lines from console java

I want to read this string (from console not file) for example:
one two three
four five six
seven eight nine
So I want to read it per line and put every line in an array.
How can I read it? Because if I use scanner, I can only read one line or one word (nextline or next).
what I mean is to read for example : one two trhee \n four five six \n seven eight nine...
You should do by yourself!
There is a similer example:
public class ReadString {
public static void main (String[] args) {
// prompt the user to enter their name
System.out.print("Enter your name: ");
// open up standard input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String userName = null;
// read the username from the command-line; need to use try/catch with the
// readLine() method
try {
userName = br.readLine();
} catch (IOException ioe) {
System.out.println("IO error trying to read your name!");
System.exit(1);
}
System.out.println("Thanks for the name, " + userName);
}
} // end of ReadString class
To answer the question as clarified in the comment on the first answer:
You must call Scanner's nextLine() method once for each line you wish to read. This can be accomplished with a loop. The problem you will inevitably encounter is "How do I know big my result array should be?" The answer is that you cannot know if you do not specify it in the input itself. You can modify your programs input specification to require the number of lines to read like so:
3
One Two Three
Four Five
Six Seven Eight
And then you can read the input with this:
Scanner s = new Scanner(System.in);
int numberOfLinesToRead = new Integer(s.nextLine());
String[] result = new String[numberOfLinesToRead];
String line = "";
for(int i = 0; i < numberOfLinesToRead; i++) { // this loop will be run 3 times, as specified in the first line of input
result[i] = s.nextLine(); // each line of the input will be placed into the array.
}
Alternatively you can use a more advanced data structure called an ArrayList. An ArrayList does not have a set length when you create it; you can simply add information to it as needed, making it perfect for reading input when you don't know how much input there is to read. For example, if we used your original example input of:
one two trhee
four five six
seven eight nine
You can read the input with the following code:
Scanner s = new Scanner(System.in);
ArrayList<String> result = new ArrayList<String>();
String line = "";
while((line = s.nextLine()) != null) {
result.add(line);
}
So, rather than creating an array of a fixed length, we can simply .add() each line to the ArrayList as we encounter it in the input. I recommend you read more about ArrayLists before attempting to use them.
tl;dr: You call next() or nextLine() for each line you want to read using a loop.
More information on loops: Java Loops
Look at this code:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class SearchInputText {
public static void main(String[] args) {
SearchInputText sit = new SearchInputText();
try {
System.out.println("test");
sit.searchFromRecord("input.txt");
System.out.println("test2");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void searchFromRecord(String recordName) throws IOException {
File file = new File(recordName);
Scanner scanner = new Scanner(file);
StringBuilder textFromFile = new StringBuilder();
while (scanner.hasNext()) {
textFromFile.append(scanner.next());
}
scanner.close();
// read input from console, compare the strings and print the result
String word = "";
Scanner scanner2 = new Scanner(System.in);
while (((word = scanner2.nextLine()) != null)
&& !word.equalsIgnoreCase("quit")) {
if (textFromFile.toString().contains(word)) {
System.out.println("The word is on the text file");
} else {
System.out.println("The word " + word
+ " is not on the text file");
}
}
scanner2.close();
}
}

Categories