I'm trying to have Java count the number of lines within a text file using hasNext(), hasNextLine(), and while loops although I seem to be having some trouble. The program will continuously run and I believe it's stuck in an infinite loop. If someone could explain the issue and give me a possible fix I'd greatly appreciate it.
Here's the file the program is reading from (hurcdata2.txt, its saved in the program's directory):
1980 Aug 945 100 Allen
1983 Aug 962 100 Alicia
1984 Sep 949 100 Diana
1985 Jul 1002 65 Bob
1985 Aug 987 80 Danny
1985 Sep 959 100 Elena
1985 Sep 942 90 Gloria
1985 Oct 971 75 Juan
1985 Nov 967 85 Kate
And here is my code:
import java.util.Scanner;
import java.io.*;
public class HurricaneData
{
public static void main(String[] args) throws IOException
{
File hurricaneData = new File("TestText.txt");
Scanner inFileHD = new Scanner(hurricaneData);
int n = 0; //represents number of blocks of data
while( inFileHD.hasNextLine() )
{
n++;
}
System.out.println(n + " block of data");
inFileHD.close();
}
}
You need to consume the input to the Scanner otherwise inFileHD.hasNextLine() will always be true
while (inFileHD.hasNextLine()) {
inFileHD.nextLine(); // add this
...
}
Related
According to this answer Java can hold up to 2^31 - 1 characters. I was trying to do benchmarking and stuffs, so I tried to create a large amount of string and write it to a file like this:
import java.io.*
fun main() {
val out = File("ouput.txt").apply { createNewFile() }.printWriter()
sequence {
var x = 0
while (true) {
yield("${++x} ${++x} ${++x} ${++x} ${++x}")
}
}.take(5000).forEach { out.println(it) }
out.close()
}
And then the output.txt file contains like this:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
// ... 5000 lines
And then I copied all the contents of the file into a string for some benchmarking of some functions, so this is how it looks:
import kotlin.system.*
fun main() {
val inputs = """
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
// ... 5000 lines
24986 24987 24988 24989 24990
24991 24992 24993 24994 24995
24996 24997 24998 24999 25000
""".trimIndent()
measureNanoTime {
inputs.reader().forEachLine { line ->
val (a, b, c, d, e) = line.split(" ").map(String::toInt)
}
}.div(5000).let(::println)
}
The total character count of the file/string is 138894
String can hold up to 2147483647
But the Kotlin code does not compile (last file) It throws compilation error:
e: org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: wrong bytecode generated
// more lines
The root cause java.lang.IllegalArgumentException was thrown at: org.jetbrains.org.objectweb.asm.ByteVector.putUTF8(ByteVector.java:246)
at org.jetbrains.kotlin.codegen.TransformationMethodVisitor.visitEnd(TransformationMethodVisitor.kt:92)
at org.jetbrains.kotlin.codegen.FunctionCodegen.endVisit(FunctionCodegen.java:971)
... 43 more
Caused by: java.lang.IllegalArgumentException: UTF8 string too large
Here is the total log of exception with stacktrace: https://gist.github.com/Animeshz/1a18a7e99b0c0b913027b7fb36940c07
There is limit in java class file, length of string constant must fit in 16 bits ie. 65535 bytes (not characters) is max length of string in source code.
The class File Format
I'm trying to add the total of each row, but I can only compute the first row total? How do I make it so that the program goes and reads each line to compute the total?
Once I do that...I want to put a if else statement in there. I want it to ask each row if there is an int that is above 30,000. For each int that is above 30,000 I want the total to add 1,000.
package finalProg;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.Scanner;
public class test
{
public static void main(String[] args)
{
readFromFile("sales.txt");
}
private static void readFromFile(String filename)
{
LineNumberReader lineNumberReader = null;
try
{
//Construct the LineNumberReader object
lineNumberReader = new LineNumberReader(new FileReader(filename));
//Setting initial line number
lineNumberReader.setLineNumber(0);
//Read all lines now; Every read increase the line number by 1
String line = null;
while ((line = lineNumberReader.readLine()) != null)
{
System.out.println("Store " + lineNumberReader.getLineNumber() + ": " + line);
File inputFile = new File("sales.txt");
Scanner a = new Scanner(inputFile);
int jan = a.nextInt();
int feb = a.nextInt();
int mar = a.nextInt();
int apr = a.nextInt();
int may = a.nextInt();
int jun = a.nextInt();
int jul = a.nextInt();
int aug = a.nextInt();
int sept = a.nextInt();
int oct = a.nextInt();
int nov = a.nextInt();
int dec = a.nextInt();
System.out.println(jan + feb + mar + apr + may + jun + jul + aug + sept + oct + nov + dec + "\n");
}
}
catch (Exception ex)
{
ex.printStackTrace();
} finally
{
//Close the LineNumberReader
try {
if (lineNumberReader != null){
lineNumberReader.close();
}
} catch (IOException ex){
ex.printStackTrace();
}
}
}
}
20000 35000 23000 50000 45000 24000 41000 39000 36000 42000 41000 39000
35000 42000 38000 41000 50000 51000 53000 50000 54000 55000 54000 56000
20000 10000 15000 12000 13000 14000 13000 14000 15000 19000 20000 21000
44000 45000 46000 42000 44000 48000 47000 46000 44000 43000 48000 49000
33000 34000 35000 36000 40000 41000 42000 40000 44000 42000 41000 39000
50000 53000 51000 52000 55000 56000 52000 54000 51000 56000 55000 53000
So far the output looks like this:
Store 1: 20000 35000 23000 50000 45000 24000 41000 39000 36000 42000 41000 39000
435000
Store 2: 35000 42000 38000 41000 50000 51000 53000 50000 54000 55000 54000 56000
435000
Store 3: 20000 10000 15000 12000 13000 14000 13000 14000 15000 19000 20000 210000
435000
Store 4: 44000 45000 46000 42000 44000 48000 47000 46000 44000 43000 48000 49000
435000
Store 5: 33000 34000 35000 36000 40000 41000 42000 40000 44000 42000 41000 39000
435000
Store 6: 50000 53000 51000 52000 55000 56000 52000 54000 51000 56000 55000 53000
435000
First of all, it's better to declare jan, feb etc. variables out of the method because it really looks like that values are not refreshed.
But I would recommend you something like this:
public class test(){
private int sum;
public static void main(String[] args)
{
readFromFile("sales.txt");
}
//You don't need this void to be static!
private void readFromFile(String filename){
LineNumberReader lineNumberReader = null;
try
{
//Construct the LineNumberReader object
lineNumberReader = new LineNumberReader(new FileReader(filename));
//Setting initial line number
lineNumberReader.setLineNumber(0);
//Read all lines now; Every read increase the line number by 1
String line = null;
while ((line = lineNumberReader.readLine()) != null)
{
System.out.println("Store " + lineNumberReader.getLineNumber() + ": " + line);
File inputFile = new File("sales.txt");
Scanner a = new Scanner(inputFile);
for (int i = 0; i < 12; i++){
sum =+ a.nextInt();
}
System.out.println(sum);
sum = 0;
}
}
catch (Exception ex)
{
ex.printStackTrace();
} finally
{
//Close the LineNumberReader
try {
if (lineNumberReader != null){
lineNumberReader.close();
}
} catch (IOException ex){
ex.printStackTrace();
}
}
}
}
This should be better.
There are a number of things that could be done differently here.
First off, consider dropping the idea of using two specific data file
readers. There is no point in this when only one file reader will do.
Take your pick and stick with it.
Whichever file reader you decide to use, make sure you close it when
done.
Don't open your data file with a new instance of a reader for every
iteration of a while loop. You're creating a hook onto that file
every time you do that and it will remain there until each reader
instance is closed or your application ends.
Declaring 12 specific int variables to hold monthly values can be best suited with the use of an Array. You need to also consider the fact that there could possibly (just possibly at some point) be a typo or error within the data which will not produce a valid integer value. This could throw a real wack-a-doodle into the workings of your code if not handled.
Below is some code that demonstrates one way you can accomplish the task at hand. It is well commented so you can see what is going on:
// Create a months header string for display purposes.
String header = String.format("%-8s %-8s %-8s %-8s %-8s %-8s %-8s %-8s %-8s %-8s %-8s %-8s",
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
"Oct", "Nov", "Dec");
// Create a header underline for display purposes.
String underline = String.join("", Collections.nCopies(header.length(), "="));
//Display a 'Start' underline for the Console display.
System.out.println(underline);
// Read the 'sales.txt' data file for monthly data of 6 stores.
// Trap the 'FileNotFoundException'.
try (Scanner reader = new Scanner(new File("sales.txt"))) {
int storeCounter = 0; // Keep track of the Store count.
long overallTotal = 0; // Maintain an Over-All total for all Stores
String line; // Used to hold current read in line data
// Iterate through the data file one line ata a time...
while (reader.hasNextLine()) {
line = reader.nextLine().trim(); // Trim leading/trailing whitespaces from read line.
if (line.equals("")) { continue; } // Skip blank lines (if any).
/* Split the line data into a String[] Array.
"\\s+" is used to split on one (or more)
whitespaces. */
String[] lineMonths = line.split("\\s+");
int yearTotal = 0; // Keep track of the line's yearly total.
storeCounter++; // Increment the Store Counter by 1.
int monthsOver30000 = 0; // Number of Months over 30000.
System.out.println("Store: " + storeCounter); // Display the Current Store Number in Console.
System.out.println(header); // Display the months header line in console.
// Display the current Store's monthly data in Console...
for (String month : lineMonths) {
// Display the current month.
System.out.printf("%-8s ", month);
// Add the current month value to the Yearly Total
// but first make sure it is in fact a valid integer
// value otherwise ignore it (don't add it to yearly).
if (month.matches("\\d+")) {
int monthValue = Integer.parseInt(month); // Convert the month value from string to integer
// Is the month value more than 30,000?
if (monthValue > 30000) {
// Yes, so add 1,000 to the Month Value
monthValue += 1000;
monthsOver30000++;
}
yearTotal += monthValue;
}
}
System.out.println(); // Add a newline to all the above printf's.
// If there were months that were over 30,000...
if (monthsOver30000 > 0) {
// Display information about it in Console.
System.out.println(); // Add a newline to separate this section.
System.out.println("There were " + monthsOver30000 + " months "
+ "for this Store where Monthly values were over 30000"
+ " therefore " + (monthsOver30000 * 1000) + " was added "
+ "to the");
System.out.println("Yearly Total.");
System.out.println(); // Add a newline to separate this section.
}
System.out.println("Yearly Total: --> " + yearTotal); // Display the yearly total in Console.
System.out.println(underline); // Display a underline so as to start a new data line.
// Add the current Year Total to the All Stores Over-All
// Total. Will be used for averaging later on.
overallTotal += yearTotal;
} // Continue iterating through data file until end of file is reached.
// Display the over-all total for all Stores Yearly totals in Console.
System.out.println("The over-all total for all " + storeCounter + " Stores: --> " + overallTotal);
// Display the yearly average for all stores contained within the data file.
System.out.println("The yearly average for all " + storeCounter + " Stores: --> " + overallTotal/storeCounter);
}
// Catch the 'FileNotFoundException' exception (if any).
catch (FileNotFoundException ex) {
// Display the Exception message if the exception was thrown.
System.err.println(ex.getMessage());
}
Based on the data you provided in your post, the outputto Console should look something like this:
===========================================================================================================
Store: 1
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
20000 35000 23000 50000 45000 24000 41000 39000 36000 42000 41000 39000
There were 9 months for this Store where Monthly values were over 30000 therefore 9000 was added to the
Yearly Total.
Yearly Total: --> 444000
===========================================================================================================
Store: 2
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
35000 42000 38000 41000 50000 51000 53000 50000 54000 55000 54000 56000
There were 12 months for this Store where Monthly values were over 30000 therefore 12000 was added to the
Yearly Total.
Yearly Total: --> 591000
===========================================================================================================
Store: 3
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
20000 10000 15000 12000 13000 14000 13000 14000 15000 19000 20000 21000
Yearly Total: --> 186000
===========================================================================================================
Store: 4
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
44000 45000 46000 42000 44000 48000 47000 46000 44000 43000 48000 49000
There were 12 months for this Store where Monthly values were over 30000 therefore 12000 was added to the
Yearly Total.
Yearly Total: --> 558000
===========================================================================================================
Store: 5
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
33000 34000 35000 36000 40000 41000 42000 40000 44000 42000 41000 39000
There were 12 months for this Store where Monthly values were over 30000 therefore 12000 was added to the
Yearly Total.
Yearly Total: --> 479000
===========================================================================================================
Store: 6
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
50000 53000 51000 52000 55000 56000 52000 54000 51000 56000 55000 53000
There were 12 months for this Store where Monthly values were over 30000 therefore 12000 was added to the
Yearly Total.
Yearly Total: --> 650000
===========================================================================================================
The over-all total for all 6 Stores: --> 2908000
The yearly average for all 6 Stores: --> 484666
I have data like given below.
11
13
15
17
25
26
29
30
17
25
26
29
30
25
26
29
30
25
26
29
30
17
25
26
29
30
17
19
In this data there are two groups of record (15,17) can occur only once at position only 3rd and 4th only. Second group is (25, 26, 29, 30) and can be occur multiple times.
Record 17 is like a break..after this new group starts and in that group multi subgroups(25,26,29,30) could be present.
I want to append two characters when ever a new group starts, and keep increment the subgroup if doesnt break by breaker record(17).
I hope its cleared.
My output data looks like this
11
13
1115
17
2125
26
29
30
17
3125
26
29
30
n225
26
29
30
n325
26
29
30
17
4125
26
29
30
17
19
tried so far..with this abstract code. But not able to handle subgroups with n character
int line=0
int seq =0
if (in.equal =15 or 25) {
line++
seq++
context.line = line++ // variable to store line variable
context.seq = seq++ // variable to store seq variable
out = context.line+context.seq+in // out is output record and in is input record mentioned in above data
flag = 1
}
else (if in.equal = 17 and flag = 1){
flag = 0
seq=0
}
Any suggestion please ?
For one of my assignments, I have to calculate the heat index and use printf to format the output to display neatly, like this:
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
________________________________________________________________________________________
Temperature (F): 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10 11 12
Humidity (%): 1 2 3 4 5 6 7 8 9 10.3 11.2 12.1
HI (F): 1.1 2.2 3.3 4.4 5 7 6 8 9 10 11 12
The problem is, I don't know how to format an array of Strings because the array of Strings contains numbers. In my program, do I have to convert my array that I declared as a String to like a double or a float and then format it with printf? Also, I don't know how I can use an array for a calculation. In my assignment, I have to use two arrays to calculate the heat index. Trying to solve this problem, I tried performing the calculations individually by indexes. The problem is, the program will just show the whole entire array. The program is reading two files and storing the text in an array, one array for each file. Any help will be greatly appreciated. The first file contains this:
70.3 70.8 73.8 77.0 80.7 83.4 84.5 84.4 83.4 80.2 76.3 72.0
and the second contains this:
69 67 66 64 66 69 67 67 70 69 69 70
and my code is this:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author timothylee
*/
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
public class HeatIndex {
/**
* #param args the command line arguments
* #throws java.io.IOException
*/
public static void main(String[] args) throws IOException{
// TODO code application logic here
// create months
System.out.println("Jan" + " Feb" + " Mar" + " April" + " May" + " June" +
" July" + " Aug" + " Sep" + " Oct" + " Nov" + " Dec");
// create line
System.out.println("_________________________________________________"
+ "__________________________________");
// // read KeyWestTemp.txt
// create token1
String token1 = "";
// create Scanner inFile1
Scanner inFile1 = new Scanner(new File
("/Users/timothylee/KeyWestTemp.txt")).
useDelimiter(",\\s*");
// create temps1
List<String> temps1 = new LinkedList<String>();
// while loop
while(inFile1.hasNext()){
// find next
token1 = inFile1.next();
// initialize temps1
temps1.add(token1);
}
// close inFile1
inFile1.close();
// create array
String[] tempsArray1 = temps1.toArray(new String[0]);
// for-each loop
for(String s : tempsArray1){
// display Temp (F)
System.out.print("Temp (F) ");
// display s
System.out.printf(tempsArray1[0]);
// create new line
System.out.println();
}
// create token2
String token2 = "";
// create Scanner inFile2
Scanner inFile2 = new Scanner(new File
("/Users/timothylee/KeyWestHumid.txt")).
useDelimiter(",\\s*");
// create temps2
List<String> temps2 = new LinkedList<String>();
// while loop
while(inFile2.hasNext()){
// find next
token2 = inFile2.next();
// initialize temps2
temps2.add(token2);
}
// close inFile2
inFile2.close();
// create array
String[] tempsArray2 = temps2.toArray(new String[0]);
// for-each loop
for(String ss : tempsArray2){
// create Humidity (%)
System.out.print("Humidity (%) ");
// display ss
System.out.printf(tempsArray2[0]);
}
// calculate heat index
}
}
and my output is this:
run:
Jan Feb Mar April May June July Aug Sep Oct Nov Dec
___________________________________________________________________________________
Temp (F) 70.3 70.8 73.8 77.0 80.7 83.4 84.5 84.4 83.4 80.2 76.3 72.0
Humidity (%) 69 67 66 64 66 69 67 67 70 69 69 70BUILD SUCCESSFUL (total time: 0 seconds)
Take a look at Formatter. You need to use the format() method, for example something like this would give you the spacing you need in your first line.
formatter.format("%15s%5s%5s%5s",months[0],months[1],months[2],months[3]); //and so on for all twelve months
As for numbers you need to use
formatter.format("%5.1f",myFloat);
The first digit denotes how many characters you use for your natural part and the second digit how many characters for your decimal part. Seeing that all your numbers have only 1 decimal digit and you need spacing between numbers, use the %5.1f format.
Hii Guys !!!
I have a string with values like 69 17 17 16 2 1 1 26 26 56 56 69 20 19 20 etc .Now As per my need i have to put these values into new String with each values in new line as after each value space is there ..
Any help will be highly appreciated..
Thanx in advance...
String newStr = origStr.replaceAll(" ", " \n");
You should split the String using a specific separator into a List.
Then print out the List using the format required.
This helps when tomorow the String contains digits, decimals, text, etc or they want the text in another format.
String source = "69 17 17 16 2 1 1 26 26 56 56 69 20 19 20";
String[] splitted = source.split(" ");
StringBuilder sb = new StringBuilder();
for (String split : splitted){
sb.append(split).append(System.getProperty("line.separator"));
}
System.out.println(sb.toString());