I'm trying to read integers from a text file, but I want to handle the first line differently from the rest, and take the following lines and loop some calculations. Below is my file reader, my question is about the next part, however this may provide some context.
public class main
{
BufferedReader in;
public main() throws FileNotFoundException
{
System.out.println("please enter the name of the text file you wish you import. Choose either inputs or lotsainputs. Nothing else");
Scanner keyboard = new Scanner(System.in);
String filename = keyboard.nextLine();
File file = new File(filename);
System.out.println("You have loaded file: \t\t"+filename);
in = new BufferedReader(new FileReader(file));
Scanner inputFile = new Scanner(file);
String element1 = inputFile.nextLine().toUpperCase();
try
{
while ((element1 = in.readLine()) != null)
{
System.out.println("Line to process:\t\t"+element1);
myCalculations(element1);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
The first text file look like this:
200 345
36
The second text file look like this:
200 345
36
45
36
21
Here is the method called:
public static void myCalculations(String s)
{
String[] items = s.split(" ");
int[] results = new int[100];
String errorMessage = "that's a wrap!";
for (int i = 0; i < items.length; i++)
{
try {
int stuff = Integer.parseInt(items[i]);
results[i] = stuff;
}
catch (NumberFormatException nfe) {
System.out.println(results);
System.out.println(errorMessage);
}
}
int health = result[0];
int power = result[1];
int days = result[2];
some calculations....
returns new health and power of the car.
same calculations but results[3] as the time period
returns new health and power of car
etc....
}
The method parses the integers, puts them into the results[] array.
Lets say the first two numbers of the text file are health and power of a car. Each proceeding number are days between races. Each race there is deterioration of the of the car and engine, the amount of deterioration is a factor of days in between each race.
I have used results[3][4]&[5] and hard code the deterioration and print the results and it works, but its pretty crap. How would I improve this method? I'm copy and pasting the 'calculations'. How do I take the first line, then put the following lines in a separate loop?
ideally, the number of days in the text file could vary. ie, there could be 5 races, or there could be 3 and the program will handle both cases.
try something like
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
System.out.println(
"please enter the name of the text file you wish you import. Choose either inputs or lotsainputs. Nothing else");
Scanner keyboard = new Scanner(System.in);
String filename = keyboard.nextLine();
File file = new File(filename);
System.out.println("You have loaded file: \t\t" + filename);
BufferedReader in = new BufferedReader(new FileReader(file));
String element1 = null;
try {
element1 = in.readLine();
}catch (Exception e) {
// TODO: handle exception
}
String[] firstLine = element1.split(" ");
Arrays.stream(firstLine).forEach(fl -> {
System.out.println("First line element: " + fl);
});
//Do the staff
String otherElement = null;
try {
while ((otherElement = in.readLine()) != null) {
System.out.println("Line to process:\t\t" + otherElement);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
result for file:
1 2
3
5
7
is
You have loaded file:
First line element: 1
First line element: 2
Line to process: 3
Line to process: 5
Line to process: 7
Related
I need a program that will ask the user to enter the information to save, line to line in a file. How can I do it?
It has to look like this:
Please, choose an option:
1. Read a file
2. Write in a new file
2
File name? problema.txt
How many lines do you want to write? 2
Write line 1: Hey
Write line 2: How are you?
Done! The file problema.txt has been created and updated with the content given.
I have tried in various ways but I have not succeeded. First I have done it in a two-dimensional array but I can not jump to the next line.
Then I tried it with the ".newline" method without the array but it does not let me save more than one word.
Attempt 1
System.out.println("How many lines do you want to write? ");
int mida = sc.nextInt();
PrintStream escriptor = new PrintStream(f);
String [][] dades = new String [mida][3];
for (int i = 0; i < dades.length; i++) {
System.out.println("Write line " + i + " :");
for (int y=0; y < dades[i].length; y++) {
String paraula = sc.next();
System.out.println(paraula + " " + y);
dades[i][y] = paraula;
escriptor.print(" " + dades[i][y]);
}
escriptor.println();
}
Attempt 2
System.out.println("How many lines do you want to write? ");
int mida = sc.nextInt();
PrintStream escriptor = new PrintStream(f);
BufferedWriter ficheroSalida = new BufferedWriter(new FileWriter(new File(file1)));
for (int i = 0; i < mida; i++) {
System.out.println("Write line " + i + " :");
String paraula = sc.next();
ficheroSalida.write (paraula);
ficheroSalida.newLine();
ficheroSalida.flush();
}
System.out.println("Done! The file " + fitxer + " has been created and updated with the content given. ");
escriptor.close();
Attempt 1:
Write line 1: Hey How are
Write line 1: you...
Attempt 2:
Write line 1: Hey
Write line 2: How
Write line 3: are
Write line 4: you
Write line 5: ?
Well, you're almost there. First, I'd use a java.io.FileWriter in order to write the strings to a file.
It's not really necessary to use an array here if you just want to write the lines to a file.
You should also use the try-with-resources statement in order to create your writer. This makes sure that escriptor.close() gets called even if there is an error. You don't need to call .flush() in this case either because this will be done before the handles gets closed. It was good that you intended to do this on your own but in general its safer to use this special kind of statement whenever possible.
import java.io.*;
import java.util.Scanner;
public class Example {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
File f = new File("/tmp/output.txt");
System.out.println("How many lines do you want to write? ");
int mida = sc.nextInt();
sc.nextLine(); // Consume next empty line
try (FileWriter escriptor = new FileWriter(f)) {
for (int i = 0; i < mida; i++) {
System.out.println(String.format("Write line %d:", i + 1));
String paraula = sc.nextLine();
escriptor.write(String.format("%s\n", paraula));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
In cases where your text file is kind of small and usage of streamreaders/streamwriters is not required, you can read the text, add what you want and write it all over again. Check this example:
public class ReadWrite {
private static Scanner scanner;
public static void main(String[] args) throws FileNotFoundException, IOException {
scanner = new Scanner(System.in);
File desktop = new File(System.getProperty("user.home"), "Desktop");
System.out.println("Yo, which file would you like to edit from " + desktop.getAbsolutePath() + "?");
String fileName = scanner.next();
File textFile = new File(desktop, fileName);
if (!textFile.exists()) {
System.err.println("File " + textFile.getAbsolutePath() + " does not exist.");
System.exit(0);
}
String fileContent = readFileContent(textFile);
System.out.println("How many lines would you like to add?");
int lineNumber = scanner.nextInt();
for (int i = 1; i <= lineNumber; i++) {
System.out.println("Write line number #" + i + ":");
String line = scanner.next();
fileContent += line;
fileContent += System.lineSeparator();
}
//Write all the content again
try (PrintWriter out = new PrintWriter(textFile)) {
out.write(fileContent);
out.flush();
}
scanner.close();
}
private static String readFileContent(File f) throws FileNotFoundException, IOException {
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
return everything;
}
}
}
An execution of the example would be:
Yo, which file would you like to edit from C:\Users\George\Desktop?
hello.txt
How many lines would you like to add?
4
Write line number #1:
Hello
Write line number #2:
Stack
Write line number #3:
Over
Write line number #4:
Flow
with the file containing after:
Hello
Stack
Over
Flow
And if you run again, with the following input:
Yo, which file would you like to edit from C:\Users\George\Desktop?
hello.txt
How many lines would you like to add?
2
Write line number #1:
Hey
Write line number #2:
too
text file will contain:
Hello
Stack
Over
Flow
Hey
too
However, if you try to do it with huge files, your memory will not be enough, hence an OutOfMemoryError will be thrown. But for small files, it is ok.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class backup {
public static void main(String[] args) {
System.out.println("\nThe names in the file are:\n");
readFromFile();
}
public static void readFromFile() {
try {
Scanner file = new Scanner(new File("Names.txt"));
PrintWriter pass = new PrintWriter("pass.txt");
PrintWriter fail = new PrintWriter("fail.txt");
Scanner input = new Scanner(System.in);
while (file.hasNext()) {
String name = file.nextLine();
System.out.printf("Please enter " + name + "'s mark:");
int mark = input.nextInt();
Scanner kybd = new Scanner(System.in);
{
if (mark >= 40) {
// System.out.println(name + " has passed");
pass.println(name);
} else {
// System.out.println(name + " has failed");
fail.println(name);
}
}
} // end while
} // end try
catch (IOException ioe) {
System.out.println("Error handling file");
} // end catch
}// readFromFile
}
Unable to write to the file pass and fail the Names file is just a list of names if the user scores over 40 they go into the pass however i cant get the txt file to populate the output.
When i insert my printwriter in the while it is only the last entry which gets added to either pass or fail txt file.
The PrintWriter only really writes when they are closed (close) or flushed (flush or maybe when it thinks it is time ;-)).
Try to use try-with-resources whenever possible, that way you do not need to think about closing/flushing a stream or writer. try-with-resources takes care that AutoClosable-implementations are closed automatically at the end of the try-block.
Your sample rewritten with try-with-resources (only showing the initial part):
try(
Scanner file = new Scanner(new File("Names.txt"));
PrintWriter pass = new PrintWriter("pass.txt");
PrintWriter fail = new PrintWriter("fail.txt")
) {
The rest can stay as is... or if you like: you may also want to lookup the Files-API. Maybe using Files.lines is something for you?
You should call the function close on your file for it to be written on the dsisk.
Otherwise you modifications are only in memory
Something like: file.close()
If you use PrintWriter, you have to close the stream at the end. Otherwise, it will be only in memory. Try this:
try {
Scanner file = new Scanner(new File("Names.txt"));
PrintWriter pass = new PrintWriter("pass.txt");
PrintWriter fail = new PrintWriter("fail.txt");
Scanner input = new Scanner(System.in);
while (file.hasNext()) {
String name = file.nextLine();
System.out.printf("Please enter " + name + "'s mark:");
int mark = input.nextInt();
//Scanner kybd = new Scanner(System.in);
//{
if (mark >= 40) {
// System.out.println(name + " has passed");
pass.println(name);
} else {
// System.out.println(name + " has failed");
fail.println(name);
}
//}
} // end while
pass.close();
fail.close();
} // end try
catch (IOException ioe) {
System.out.println("Error handling file");
}
You need to make sure that you add a finally block at the end and call the close method on anything that is closeable so in this case on the printwriter. In this case
pass.close() and fail.close().
I am writing a program to take in a file and output a file.
The input file contains like:
1 cat dog rabbit
3 cat dog rabbit rabbit rabbit
2 yellow red blue white black
0 three two one
and the output file would be:
dog rabbit rabbit rabbit blue white black three two one
(the program takes in the integer at the beginning of each line and then skip the number of words in each line and then save the rest words and output them to a file)
Initially, I have
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.File;
import java.io.PrintWriter;
public class Scanner2{
public static void main(String args[]) {
String c = "";
try{
File file = new File(args[0]);
Scanner scanner = new Scanner(file);
PrintWriter writer = new PrintWriter(args[1]);
// as long as the scanner reads that the file has a next line
while (scanner.hasNextLine()) {
// read the next line of string as string s
String s = scanner.nextLine();
// split each word from the string s as an array called "words"
String[] words = s.split(" ");
// for loop executed length of "words" times
for(int x = 0; x < words.length; x++) {
// declare int, "count"
int count;
// parse the first element (the number) from "words" to be an integer, "count"
count = Integer.parseInt(words[0]);
// if the loop is executed more than "count" number of times
if (x > count){
// add respective element to string, "c"
c += words[x];
c += " ";
}
}
}
// close the scanner
scanner.close();
// output string "c" to the output file
writer.println(c);
// close the writer
writer.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
and these codes work perfectly.
However, now I want to switch from using the split method to another second scanner class to read each sentence to each word.
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.File;
import java.io.PrintWriter;
public class ScannerDemo{
public static void main(String args[]) {
String c = "";
try{
File file = new File(args[0]);
Scanner scanner = new Scanner(file);
PrintWriter writer = new PrintWriter(args[1]);
// as long as the scanner reads that the file has a next line
while (scanner.hasNextLine()) {
// read the first line of string in scanner s2
Scanner s2 = new Scanner(scanner.nextLine());
// read the first word of first line from s2 as string "counts"
String counts = s2.next();
// parse the string "counts" as int, "count"
int count = Integer.parseInt(counts);
// as long as s2 has the next element
while (s2.hasNext()){
// for loop executed "count" number of times to skip the words
for (int x = 0; x < count; x ++){
String b = s2.next();
}
// else add the next words to string, "c"
c += s2.next();
c += " ";
}
}
// close the scanner
scanner.close();
// output string "c" to the output file
writer.println(c);
// close the writer
writer.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
However, it gives out error message
Exception in thread "main" java.util.NoSuchElementException
I felt this error message is due to the second scanner class not closed properly. However, I did not figure out how to solve it after I added
s2.close();
in the for loop.
Any help is appreciated. Thank you but I am really new to Java,
There is a bug in the nested while and for loops that causes the s2.next() in the for loop to go of the end of the line. Try as follows
// parse the string "counts" as int, "count"
int count = Integer.parseInt(counts);
// for loop executed "count" number of times to skip the words
for (int x = 0; x < count && s2.hasNext(); x++){
String b = s2.next();
}
// as long as s2 has the next element add the next words to string
while (s2.hasNext()) {
c += s2.next();
c += " ";
}
Also, it is recommended to use try with resources instead of closing yourself. Simplified example :
try (Scanner scanner = new Scanner(file);
PrintWriter writer = new PrintWriter(args[1]);) {
scanner.next();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
This way the scanner and writer will be closed automatically even if an exception is thrown.
For example you can use a StringTokenizer instead of a second Scanner:
while(scanner.hasNextLine())
{
StringTokenizer tokenizer = new StringTokenizer(scanner.nextLine());
int count = Integer.parseInt(tokenizer.nextToken());
while(tokenizer.hasMoreTokens())
{
String b = tokenizer.nextToken() + " ";
if(count <= 0)
{
c += b;
}
count--;
}
}
scanner.close();
I think your problem with the second scanner was the inner loop and the scanner position - you want to advance it the number of words it has and only add some to your output string.
My application here prompts the user for a text file, mixed.txt which contains
12.2 Andrew
22 Simon
Sophie 33.33
10 Fred
21.21 Hank
Candice 12.2222
Next, the application is to PrintWrite to all text files namely result.txt and errorlog.txt. Each line from mixed.txt should begin with a number first followed by a name. However, certain lines may contain the other way round meaning to say name then followed by a number. Those which begins with a number shall be added to a sum variable and written to the result.txt file while those lines which begin with the name along with the number shall be written to the errorlog.txt file.
Therefore, on the MS-DOS console the results are as follow:
type result.txt
Total: 65.41
type errorlog.txt
Error at line 3 - Sophie 33.33
Error at line 6 - Candice 12.2222
Ok here's my problem. I only managed to get up to the stage whereby I have had all numbers added to result.txt and names to errorlog.txt files and I have no idea how to continue from there onwards. So could you guys give me some advice or help on how to achieve the results I need?
Below will be my code:
import java.util.*;
import java.io.*;
class FileReadingExercise3 {
public static void main(String[] args) throws FileNotFoundException
{
Scanner userInput = new Scanner(System.in);
Scanner fileInput = null;
String a = null;
int sum = 0;
do {
try
{
System.out.println("Please enter the name of a file or type QUIT to finish");
a = userInput.nextLine();
if (a.equals("QUIT"))
{
System.exit(0);
}
fileInput = new Scanner(new File(a));
}
catch (FileNotFoundException e)
{
System.out.println("Error " + a + " does not exist.");
}
} while (fileInput == null);
PrintWriter output = null;
PrintWriter output2 = null;
try
{
output = new PrintWriter(new File("result.txt")); //writes all double values to the file
output2 = new PrintWriter(new File("errorlog.txt")); //writes all string values to the file
}
catch (IOException g)
{
System.out.println("Error");
System.exit(0);
}
while (fileInput.hasNext())
{
if (fileInput.hasNextDouble())
{
double num = fileInput.nextDouble();
String str = Double.toString(num);
output.println(str);
} else
{
output2.println(fileInput.next());
fileInput.next();
}
}
fileInput.close();
output.close();
output2.close();
}
}
This is the screenshot of the mixed.txt file:
You can change your while loop like this:
int lineNumber = 1;
while (fileInput.hasNextLine()) {
String line = fileInput.nextLine();
String[] data = line.split(" ");
try {
sum+= Double.valueOf(data[0]);
} catch (Exception ex) {
output2.println("Error at line "+lineNumber+ " - "+line);
}
lineNumber++;
}
output.println("Total: "+sum);
Here you can go through each line of the mixed.txt and check if it starts with a double or not. If it is double you can just add it to sum or else you can add the String to errorlog.txt. Finaly you can add the sum to result.txt
you should accumulate the result and after the loop write the summation, also you can count the lines for error using normal counter variable. for example:
double mSums =0d;
int lineCount = 1;
while (fileInput.hasNext())
{
String line = fileInput.nextLine();
String part1 = line.split(" ")[0];
if ( isNumeric(part1) ) {
mSums += Double.valueOf(part1);
}
else {
output2.println("Error at line " + lineCount + " - " + line);
}
lineCount++;
}
output.println("Totals: " + mSums);
// one way to know if this string is number or not
// http://stackoverflow.com/questions/1102891/how-to-check-if-a-string-is-a-numeric-type-in-java
public static boolean isNumeric(String str)
{
try
{
double d = Double.parseDouble(str);
}
catch(NumberFormatException nfe)
{
return false;
}
return true;
}
this will give you the result you want in error files:
Error at line 3 - Sophie 33.33
Error at line 6 - Candice 12.2222
I'm trying to write a program that prompts the user to enter a character, and count the number of instances said character appears in a given file. And display the number of times the character appears.
I'm really at a loss, and I'm sorry I don't have much code yet, just don't know where to go from here.
import java.util.Scanner;
import java.io.*;
public class CharCount {
public static void main(String[] args) throws IOException {
int count = 0;
char character;
File file = new File("Characters.txt");
Scanner inputFile = new Scanner(file);
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter a single character");
character = keyboard.nextLine().charAt(0);
}
}
You need the below code to read from the file and check it with the character you've entered. count will contain the occurrences of the specified character.
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) !=null) {
for(int i=0; i<line.length();i++){
if(line.charAt(i) == character){
count++;
}
}
}
} catch (FileNotFoundException e) {
// File not found
} catch (IOException e) {
// Couldn't read the file
}