reading string and integers from a text file in java - java

/*This assignment is to create 2 parallel arrays – jobs& salaries
*Read file from “careers.txt” into arrays
*one line – job
*next line –salary
*Sort Salaries {from highest}
*then swap jobs if salary swapped
*Display output of careers and salaries from the highest on a formatted table.
*
*/
package assignment7;
import java.util.*;//importing Scanner
public class Coordinator
{
public static void main(String[] args) throws Exception
{// the main method creates the arrays and calls on each method to perform
//its work.
String [] job = new String[20];//creating a string array having 20 spaces
int[] salary = new int[20];//creating an integer array having 20 spaces
int count;// number of spaces actually occupied in the array
**count = readFile(job, salary);**// calling a method to read text into both
//arrays and return the number of spaces
//occupied in the array
sorter(job,salary,count);// calling on method to arrange file from highest
//to lowest
display(job, salary,count);// calling on method present the output
}
public static int readFile(String[] jobber, int[] salaro) throws Exception
{ // this method reads a text file and copies into arrays and also
//returns the number of spaces occupied in the array
int n = 0; //keeps track of number of times a line is fed into an
//array
//set up a file class object linked up to the name of the file to
//be read
java.io.File unread = new java.io.File("career.txt");
// create a scanner instance to read the input from the file
Scanner infile = new Scanner(unread);
/*This while loop reads line of text into the arrays, it uses
* boolean
* function hasNextLine() and the created scanner instance.
*/
while (infile.hasNextLine() || infile.hasNextInt())
{
jobber[n] = infile.nextLine();
**salaro[n] = infile.nextInt()**;
n++;
}//end while
infile.close();//close scanner class
return n;// return number of spaces filled
}//end of readFile method
public static void sorter(String[] jobestic, int[] salawe, int z)
throws Exception
{// this method sorts the array from the highest paid job to the lowest.
boolean swapped;// keeps track of when a swap takes place
int i;// variable fo for loop
int temp;// helps in swap
String temp2;// helps in swap
do
{
swapped = false;
for (i= 0; i < z-1; i++)// a pass through the array
{
if (salawe[i+1] > salawe[i])
// if the number before it is less they swap
{
//swap starts
temp = salawe[i+1];
salawe[i+1] = salawe[i];
salawe[i] = temp;
//swaps the jobs too if the salary is swapped
temp2 = jobestic[i+1];
jobestic[i+1] = jobestic[i];
jobestic[i] = temp2;
swapped = true;
}// end if
}// end for
} while (swapped);
}// end sorter method
public static void display(String[] jobo, int[] salary5 ,int k) throws Exception
{
//this method displays the output as a formatted table
int i;
System.out.printf("%-60s%15s%n", "Job", "Salary");
for(i=0; i<k; i++)
System.out.printf("%-60s%,15d%n", jobo[i], salary5[i]);
}
}
Please Guys, what is wrong with this code? I have racked my brain over and over and can't figure out what is wrong.... I ran this code but i keep getting errors... The errors always indicate the bolded lines. The text file I'm trying to read from is below. I want to store the job titles in one array and the corresponding salaries in the other array. Like Parallel arrays. Please what is wrong with the code? I want to store the salaries as integers because i have format it as integers when I present the output.
Thank you.
Computer and Information Research Scientists
102190
Computer and Information Analysts
80460
Computer Systems Analysts
79680
Information Security Analysts
86170
Software Developers and Programmers
87100
Computer Programmers
74280
Software Developers(Applications)
90060
Software Developers(Systems Software)
99000
Web Developers
62500
Database and Systems Administrators and Network Architects
76880
Database Administrators
77080
Network and Computer Systems Administrators
72560
Computer Network Architects
91000
Computer Support Specialists
48900
Computer User Support Specialists
46420
Computer Network Support Specialists
59090
The error:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at assignment7.Coordinator.readFile(Coordinator.java:56)
at assignment7.Coordinator.main(Coordinator.java:25)

This question, or its equivalent, seems to get asked every few days.
When you call nextInt(), your scanner stops after the number. Then when you call nextLine() immediately afterwards, you're actually reading the new-line character at the end of the line that had the number on. You're not reading the next line. So on the next iteration of the loop, you're calling nextInt() when you've got non-numeric text lined up next in your scanner.
Add an extra call to nextLine() after every call to nextInt(), just to read that extra new-line character.

Related

why can int not be deferenced?

I'm writing a while loop program and this problem keeps staying here and I'm not sure how to fix it. Keeps displaying "int cannot be dereferenced". I have done a ton of research on this problem and I don't know what am I doing wrong: read on google, read on StackOverflow and so on, but I don't know what to do. Tried the parsing technique but kept saying "scanner cannot convert string to int" Here is my code, any help would be appreciated. I could have declared the variable in the if and else if conditions, but I would like to keep track of what I am doing and I believe it's better to not repeat codes. (such as print out statement)
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner Data = new Scanner (System.in);
final int goldplated = 100, fourteen = 500, eighteen = 1000;
int total = 0, count = 1, size = 0;
String GetInfo = "";
System.out.println("How many times do you want to purchase:");
int EnterData = Data.nextInt();
while(count<=EnterData){
System.out.println("What Kind of Chain do you want to buy? Below are the list of options: \n 1 - gold plated \n 2 - 14k gold \n 3 - 18k gold");
//GetInfo = Data.next();
if (Data.equals("1")||Data.equals("gold plated")){
System.out.println("Please specify the length of the chain.");
size.nextInt();
total = size * goldplated;
}else if(Data.equals("2")||Data.equals("14k gold")){
System.out.println("Please specify the length of the chain.");
size.nextInt();
total = size * fourteen;
}else if(Data.equals("3")||Data.equals("18k gold")){
System.out.println("Please specify the length of the chain.");
size.nextInt();
total = size * eighteen;
}else{
System.out.println("Invalid operation");
} count++;
total+= size.nextInt();
System.out.println("This is your price: " + total);
}
}
}
nextInt() is a method in the Scanner class. So when you write something.nextInt(), the something part will have to be a Scanner object. And in your case, you've got a Scanner object, which you've called Data (not the best name for it, but never mind).
If you write Data.nextInt(), your program will wait for the user to type in a number, and return that number. That's what you want, but you'll want a variable to assign that number to, so that you can use it. That variable is size. So every time you've written size.nextInt(); in your program, what you actually need to write instead is size = Data.nextInt(); - that is, call the method on the Data object, and assign the result to the size variable.

Issue with parallel arrays and reading integers / doubles from file

I have an issue with parallel arrays and getting the program to read integers and doubles. For example, I have a text file with these values:
1234 99.58
5678 1854.99
The first number being an account number and the second number being the balance of the account. I'm not sure how to get them into a parallel array (int[] accountnumber, double[] balance) while going down the list of ideally 10+ accounts and balances.
I've tried filling the arrays separately without success, which doesn't feel like the most efficient method possible. I've tried breaking down the "(int = 0; i < maxAccts; i++)" so I could use the "i" variable for both without resetting it.
public static int readAccts(int[] acctNum, double[] balance, int maxAccts, File myinput, Scanner inputFile) throws IOException {
maxAccts = 0;
while(inputFile.hasNextInt()) {
//Test for reading integers accurately
//System.out.println(inputFile.nextInt());
maxAccts++;
inputFile.nextLine();}
//Test for maxAccts
System.out.println(maxAccts);
acctNum = new int[maxAccts];
balance = new double[maxAccts];
Scanner AccountFiller = new Scanner(myinput);
while(inputFile.hasNext());{
int i = 0;
while (i < maxAccts) {
acctNum[i] = AccountFiller.nextInt();
balance[i] = inputFile.nextDouble();
i++;}
//for (int i = 0; i < maxAccts; i++)
System.out.println(acctNum[1]);}
return maxAccts;
}
I keep getting this error below:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextDouble(Unknown Source)
At this point, I don't know why it's going wrong. In my head the cursor in the document should be right after the integer (account number), and I'm not getting an issue with that part.
You might want to fix your while loop
Your second while loop looks like this:
while(inputFile.hasNext());{
Which has a semicolon between the while and the curly brace, which means that the body of the loop is empty and after it is done looping, you run the code inside the curly braces.
The loop should be like this:
while(inputFile.hasNext()) {
This causes the error of reading the nextDouble since we just consumed the scanner's source until there is no next.
You might also want to check again how you want to read the file, since the first part doesnt really make much sense to me, it appears you just skip over all ints found in the file (while counting how many times you skip)

Out of Bounds Exception, need advice

I've read gone through the tutorials, so by all means, if you see something that I've done wrong here, please tell me so I can learn to better-participate on this site.
The getPerishedPassengers method below is giving me an out of bounds exception. I have researched and researched, and I seem to be populating the array properly, and I don't know what is wrong with the method that I've created either. Could someone guide me in the right direction as to how to overcome this exception? Thank you folks!
Here's the main/method:
int passengerMax = 2000;
int passengerActual = 0;
//Create a 2D array that will store the data from the .txt file
String[][] passengerData = new String[passengerMax][6];
//Constructor to read the file and store the data in the array
Titanic(String file) throws FileNotFoundException {
try (Scanner fileIn = new Scanner(new File(file))) {
//Conditional for reading the data
while (fileIn.hasNextLine()) {
//tab through the data to read
passengerData[passengerActual++] = fileIn.nextLine().split("\t");
}
}
}
public int getTotalPassengers() {
return passengerActual;
}
//Method for getting/returning the number of passengers that perished
public int getPerishedPassengers() {
int count = 0;
//For loop w/conditional to determine which passengers perished
for (int i = 0; i < getTotalPassengers(); i++) {
int survive = Integer.parseInt(passengerData[i][1]);
/*The program reads the file and if 1, the passenger survived. If 0,
the passenger perished. Conditional will add to the count if they
survived*/
if (survive == 0) {
count++;
}
}
return count;
}
Here's the stacktrace I'm receiving. I can include the test code as well if you folks would like. Thanks in advance:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at titanic.Titanic.getPerishedPassengers(Titanic.java:66)
at titanic.testTitanic.main(testTitanic.java:68)
Java Result: 1
From what I can see above, the issue is in the line:
int survive = Integer.parseInt(passengerData[i][1]);
My best guess, lacking your input file, is that when you are reading the file, at least one line creates an array of length 0 or 1. In all likelihood, if the last line of the file is an empty line, it would be this line which is causing your array out of bounds exception, as the split would create an array of length 0. Another cause would be a line which lacks any tab in it at all (say a space instead of tabs, etc.) will create a length 1 array, of which passengerData[i][1] will not exist, only passengerData[i][0] will.
Assuming that your input file does not have any lines which are improperly formatted / lack the appropriate number of tabs, I would suggest changing this line in the file read loop:
passengerData[passengerActual++] = fileIn.nextLine().split("\t");
to:
String incomingLine = fileIn.nextLine().trim();
if (null != incomingLine && !incomingLine.isEmpty()) {
passengerData[passengerActual++] = incomingLine.split("\t");
}

Java: Saving User Input to be Calculated in a Loop

Unfortunately, I can't attach my overall program (as it is not finished yet and still remains to be edited), so I will try my best to articulate my question.
Basically, I'm trying to take an integer inputted by the user to be saved and then added to the next integer inputted by the user (in a loop).
So far, I've tried just writing formulas to see how that would work, but that was a dead end. I need something that can "save" the integer entered by the user when it loops around again and that can be used in calculations.
Here is a breakdown of what I'm trying to make happen:
User inputs an integer (e.g. 3)
The integer is saved (I don't know how to do so and with what) (e.g. 3 is saved)
Loop (probably while) loops around again
User inputs an integer (e.g. 5)
The previously saved integer (3) is added to this newly inputted integer (5), giving a total of (3 + 5 =) 8.
And more inputting, saving, and adding...
As you can probably tell, I'm a beginner at Java. However, I do understand how to use scanner well enough and create various types of loops (such as while). I've heard that I can try using "var" to solve my problem, but I'm not sure how to apply "var". I know about numVar, but I think that's another thing entirely. Not to mention, I'd also like to see if there are any simpler solutions to my problem?
Okay So what you want is to store a number.
So consider storing it in a variable, say loopFor.
loopFor = 3
Now we again ask the user for the input.
and we add it to the loopFor variable.
So, we take the input using a scanner maybe, Anything can be used, Scanner is a better option for reading numbers.
Scanner scanner = new Scanner(System.in);//we create a Scanner object
int numToAdd = scanner.nextInt();//We use it's method to read the number.
So Wrapping it up.
int loopFor = 0;
Scanner scanner = new Scanner(System.in);//we create a Scanner object
do {
System.out.println("Enter a Number:");
int numToAdd = scanner.nextInt();//We use it's method to read the number.
loopFor += numToAdd;
} while (loopFor != 0);
You can just have a sum variable and add to it on each iteration:
public static void main(String[] args) {
// Create scanner for input
Scanner userInput = new Scanner(System.in);
int sum = 0;
System.out.println("Please enter a number (< 0 to quit): ");
int curInput = userInput.nextInt();
while (curInput >= 0) {
sum += curInput;
System.out.println("Your total so far is " + sum);
System.out.println("Please enter a number (< 0 to quit): ");
}
}
You will want to implement a model-view-controller (mvc) pattern to handle this. Assuming that you are doing a pure Java application and not a web based application look at the Oracle Java Swing Tutorial to learn how to build your view and controller.
Your model class is very simple. I would suggest just making a property on your controller that is a Java ArrayList of integers eg at the top of your controller
private Array<Integer> numbers = new ArrayList<Integer>();
Then your controller could have a public method to add a number and calculate the total
public void addInteger(Integer i) {
numbers.addObject(i);
}
public Integer computeTotal() {
Integer total = 0;
for (Integer x : numbers) {
total += x;
}
return total;
}
// This will keep track of the sum
int sum = 0;
// This will keep track of when the loop will exit
boolean errorHappened = false;
do
{
try
{
// Created to be able to readLine() from the console.
// import java.io.* required.
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(System.in));
// The new value is read. If it reads an invalid input
// it will throw an Exception
int value = Integer.parseInt(bufferReader.readLine());
// This is equivalent to sum = sum + value
sum += value;
}
// I highly discourage the use Exception but, for this case should suffice.
// As far as I can tell, only IOE and NFE should be caught here.
catch (Exception e)
{
errorHappened = true;
}
} while(!errorHappened);

How to speed up/optimize file write in my program

Ok. I am supposed to write a program to take a 20 GB file as input with 1,000,000,000 records and create some kind of an index for faster access. I have basically decided to split the 1 bil records into 10 buckets and 10 sub-buckets within those. I am calculating two hash values for the record to locate its appropriate bucket. Now, i create 10*10 files, one for each sub-bucket. And as i hash the record from the input file, i decide which of the 100 files it goes to; then append the record's offset to that particular file.
I have tested this with a sample file with 10,000 records. I have repeated the process 10 times. Effectively emulating a 100,000 record file. For this it takes me around 18 seconds. This means its gonna take me forever to do the same for a 1 bil record file.
Is there anyway i can speed up/ optimize my writing.
And i am going through all this because i can't store all the records in main memory.
import java.io.*;
// PROGRAM DOES THE FOLLOWING
// 1. READS RECORDS FROM A FILE.
// 2. CALCULATES TWO SETS OF HASH VALUES N, M
// 3. APPENDING THE OFFSET OF THAT RECORD IN THE ORIGINAL FILE TO ANOTHER FILE "NM.TXT" i.e REPLACE THE VALUES OF N AND M.
// 4.
class storage
{
public static int siz=10;
public static FileWriter[][] f;
}
class proxy
{
static String[][] virtual_buffer;
public static void main(String[] args) throws Exception
{
virtual_buffer = new String[storage.siz][storage.siz]; // TEMPORARY STRING BUFFER TO REDUCE WRITES
String s,tes;
for(int y=0;y<storage.siz;y++)
{
for(int z=0;z<storage.siz;z++)
{
virtual_buffer[y][z]=""; // INITIALISING ALL ELEMENTS TO ZERO
}
}
int offset_in_file = 0;
long start = System.currentTimeMillis();
// READING FROM THE SAME IP FILE 20 TIMES TO EMULATE A SINGLE BIGGER FILE OF SIZE 20*IP FILE
for(int h=0;h<20;h++){
BufferedReader in = new BufferedReader(new FileReader("outTest.txt"));
while((s = in.readLine() )!= null)
{
tes = (s.split(";"))[0];
int n = calcHash(tes); // FINDING FIRST HASH VALUE
int m = calcHash2(tes); // SECOND HASH
index_up(n,m,offset_in_file); // METHOD TO WRITE TO THE APPROPRIATE FILE I.E NM.TXT
offset_in_file++;
}
in.close();
}
System.out.println(offset_in_file);
long end = System.currentTimeMillis();
System.out.println((end-start));
}
static int calcHash(String s) throws Exception
{
char[] charr = s.toCharArray();;
int i,tot=0;
for(i=0;i<charr.length;i++)
{
if(i%2==0)tot+= (int)charr[i];
}
tot = tot % storage.siz;
return tot;
}
static int calcHash2(String s) throws Exception
{
char[] charr = s.toCharArray();
int i,tot=1;
for(i=0;i<charr.length;i++)
{
if(i%2==1)tot+= (int)charr[i];
}
tot = tot % storage.siz;
if (tot<0)
tot=tot*-1;
return tot;
}
static void index_up(int a,int b,int off) throws Exception
{
virtual_buffer[a][b]+=Integer.toString(off)+"'"; // THIS BUFFER STORES THE DATA TO BE WRITTEN
if(virtual_buffer[a][b].length()>2000) // TO A FILE BEFORE WRITING TO IT, TO REDUCE NO. OF WRITES
{ .
String file = "c:\\adsproj\\"+a+b+".txt";
new writethreader(file,virtual_buffer[a][b]); // DOING THE ACTUAL WRITE PART IN A THREAD.
virtual_buffer[a][b]="";
}
}
}
class writethreader implements Runnable
{
Thread t;
String name, data;
writethreader(String name, String data)
{
this.name = name;
this.data = data;
t = new Thread(this);
t.start();
}
public void run()
{
try{
File f = new File(name);
if(!f.exists())f.createNewFile();
FileWriter fstream = new FileWriter(name,true); //APPEND MODE
fstream.write(data);
fstream.flush(); fstream.close();
}
catch(Exception e){}
}
}
Consider using VisualVM to pinpoint the bottlenecks. Everything else below is based on guesswork - and performance guesswork is often really, really wrong.
I think you have two issues with your write strategy.
The first is that you're starting a new thread on each write; the second is that you're re-opening the file on each write.
The thread problem is especially bad, I think, because I don't see anything preventing one thread writing on a file from overlapping with another. What happens then? Frankly, I don't know - but I doubt it's good.
Consider, instead, creating an array of open files for all 100. Your OS may have a problem with this - but I think probably not. Then create a queue of work for each file. Create a set of worker threads (100 is too many - think 10 or so) where each "owns" a set of files that it loops through, outputting and emptying the queue for each file. Pay attention to the interthread interaction between queue reader and writer - use an appropriate queue class.
I would throw away the entire requirement and use a database.

Categories

Resources