Fill in string array with sentinel - java

So what I'm trying to do is to fill an array of 100 items with 30 names from a file using Scanner = new Scanner(new File("list.txt")). It needs to use a sentinel of "DONE" to end the loop found at the bottom of the file.
How would I do that? array[arraySize] = value(); gives me a type mismatch
public class List
{
public static void main(String[] args) throws FileNotFoundException
{
double array[] = new double[100];
int arraySize = 0;
String value;
String sentinel = "DONE";
Scanner inFile = new Scanner(new File("list.txt"));
value = inFile.next();
while (value != sentinel)
{
array[arraySize] = value();
arraySize++;
value = inFile.next();
}
}
}
D'oh....those mistakes are shameful lol. Thanks all got it to work =]

A few issues, you need to change these lines from:
double array[] = new double[100]; // can't assign string to double
// (since you said "30 names", I assume
// you aren't trying to get numbers from
// the file)
...
while (value != sentinel) // this performs pointer comparison, whereas you want
// string comparison
...
array[arraySize] = value(); // value is a variable, not a function
To:
String array[] = new String[100];
...
while (!value.equals(sentinel))
...
array[arraySize] = value;
Note: Additionally, as good practice, you might want to add some defensive programming checks to augment your while loop terminating condition. (Consider what happens when the input file does not contain a sentinel)

Related

Reading a file with Strings and floats and assigning them to arrays

I want to design a code that can read a file that looks like this:
Jake 12.00 13.24 6
Sarah 11.23 24.01 8
Alex 10.65 19.45 4
I need to make separate arrays for the Strings, the first float, the second float, and the int.
How do I go about doing this?
This is what I have so far: I'm not sure how to make separate arrays for the two floats. I also keep getting an exception IndexOutOfBoundsException: 0 at EmployeePay.main..
import java.util.Scanner;
import java.io.*;
public class EmployeePay {
public static void main(String[] args) throws FileNotFoundException {
if (args.length != 1) {
final String msg = "Usage: EmployeePay name_of_input file";
System.err.println(msg);
throw new IllegalArgumentException(msg);
}
final String inputFileName = args[0];
final File input = new File (inputFileName);
final Scanner scanner = new Scanner(new BufferedReader(new FileReader(input)));
String Id = "Employee Id:";
String Hours = "Hours worked:";
String WageRate = "Wage Rate:";
String Deductions = "Deductions:";
System.out.printf("%s %-10s %-20s %-30s", Id, Hours, WageRate, Deductions);
int lineNumber = 0;
while (scanner.hasNextLine()){
lineNumber =lineNumber +1;
String [] Identification= new String [lineNumber-1];
int [] TotalDeductions = new int [lineNumber-1];
float [] WorkTime = new float[lineNumber-1];
if(scanner.hasNextInt()){
TotalDeductions[lineNumber-1] = scanner.nextInt();
System.out.println(TotalDeductions[lineNumber-1]);
}
else if (scanner.hasNextFloat()){
WorkTime[lineNumber-1]= scanner.nextFloat();
}
else {
Identification[lineNumber-1] = scanner.next();
System.out.println(Identification[lineNumber-1]);
}
}
}
}
I will assume your String value doesn't contain space. This is kind of pseudo code, Try yourself and explore each line why I did so:
String s[] = new String[size];
float f1[] = new float[size];
float f2[] = new float[size];
for(int i=0; i<numberOfLines;i++) {
String x = "Jake 12.00 13.24 6";
String[] arr = x.split(" ");
s[i] = arr[0];
f1[i] = Float.valueOf(arr[1]);
f2[i] = Float.valueOf(arr[2]);
}
This error exception IndexOutOfBoundsException: 0 at EmployeePay.main. is occuring due to this statement if (args.length != 1).
It should be if(args.length!=0)
If no arguements are passed at command prompt then args.length is 0. So, this statement will throw an exception final String inputFileName = args[0];
Thus, you need to check for args.length
If your data file is indeed as you show in your post with blank lines between the data lines then you will need to take care of those as well while reading the file and processing the information obtained. You obviously want to skip past those particular lines. If this isn't the case then it only goes to show you how important it is to provide full and accurate information when asking a question here. No one here wants to really assume anything.
When creating arrays it's always nice to know how big an array needs to be beforehand so that you can properly initialize it to its required size. This is where List or ArrayList is better, you can just add to them when needed. Never the less, to properly initialize all your different arrays (String[], float[], float[], and int[]) you need to know how many valid data line are contained within your data file. By valid data lines I mean lines that actually contain data, not blank lines. So the first natural step would be to count those lines. Once you have the count then you can initialize all your arrays to that line count.
Now all you need to do is re-read the file data line by line, split each line to acquire the data segments , then convert each numerical segment to its respective Array data type. Once you have all your arrays filled from the file you can then do whatever you like with the data contained within those arrays. The code to carry out this task might look something like this:
String inputFileName = "MyDataFile.txt";
Scanner scanner;
int linesCount = 0;
try {
// Count the total number of valid data lines
// within the file (blank line are skipped).
scanner = new Scanner(new File(inputFileName));
while (scanner.hasNextLine()) {
String strg = scanner.nextLine().trim();
if (!strg.equals("")) { linesCount++; }
}
// Declare our different Arrays and size them to
// the valid number of data lines in file.
String[] employeeID = new String[linesCount];
float[] hours = new float[linesCount];
float[] wageRate = new float[linesCount];
int[] deductions = new int[linesCount];
// Read through the file again and place the data
// into their respective arrays.
scanner = new Scanner(new File(inputFileName));
int counter = 0;
while (scanner.hasNextLine()){
// Get the next line in file...
String strg = scanner.nextLine().trim();
// If the file line is blank then skip it.
if (strg.equals("")) { continue; }
// otherwise split the line by its space
// delimiter ("\\s+" takes care of 1 OR more
// spaces just in case).
String[] values = strg.split("\\s+");
// Add to the employeeID string array.
employeeID[counter] = values[0];
// Control what is placed into the elements of each
// float or integer array. If there is no value data
// supplied in file for the employee Name then make
// sure 0.0 (for floats) or 0 (for integers) is placed
// there after all, you can't parse a null string ("").
if (values.length >= 2) { hours[counter] = Float.parseFloat(values[1]); }
else { hours[counter] = 0.0f; }
if (values.length >= 3) { wageRate[counter] = Float.parseFloat(values[2]); }
else { wageRate[counter] = 0.0f; }
if (values.length == 4) { deductions[counter] = Integer.parseInt(values[3]); }
else { deductions[counter] = 0; }
counter++;
}
scanner.close();
// Now that you have all your arrays you can
// do whatever you like with the data contained
// within them:
String Id = "Employee Id:";
String Hours = "Hours worked:";
String WageRate = "Wage Rate:";
String Deductions = "Deductions:";
System.out.printf("%-15s %-15s %-15s %-15s%n", Id, Hours, WageRate, Deductions);
for (int i = 0; i < employeeID.length; i++) {
System.out.printf("%-15s %-15s %-15s %-15s%n", employeeID[i], hours[i], wageRate[i], deductions[i]);
}
}
catch (FileNotFoundException ex) { ex.printStackTrace(); }

Simple issue about possible to re use java Scanner?

I am still new to java and is it possible to re use the Scanner object?
The below example is I am reading a file to do characters, words and lines count. I know there must be a better way to do counting with one scanner object only but that is not the main point. I just wonder why there is input.close() but no input.open() or input.reset etc.. Since I am actually reading the same file, is it possible to create only one Scanner object and pass for 3 methods to use? Thanks
public class Test {
/**
* #throws java.io.FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
File file = new File("demo.java");
Scanner input = new Scanner(file);
Scanner input2 = new Scanner(file);
Scanner input3 = new Scanner(file);
int lines = 0;
int words = 0;
int characters = 0;
checkCharacters(input3);
checkLines(input);
checkwords(input2);
}
private static void checkLines(Scanner input) {
int count = 0;
while (input.hasNext()) {
String temp = input.nextLine();
String result = temp;
count++;
}
System.out.printf("%d lines \n", count);
}
private static void checkwords(Scanner input2) {
int count = 0;
while (input2.hasNext()) {
String temp = input2.next();
String result = temp;
count++;
}
System.out.printf("%d words \n", count);
}
private static void checkCharacters(Scanner input3) {
int count = 0;
while (input3.hasNext()) {
String temp = input3.nextLine();
String result = temp;
count += temp.length();
}
System.out.printf("%d characters \n", count);
}
}
No, there's no way to reset the Scanner from a method on the Scanner. You might be able to do it if you passed in an InputStream into the scanner and then reset the stream directly but I don't think it's worth it.
You seem to be parsing the same file 3 times and processing the same input 3 times. That seems like a waste of processing. Couldn't you perform all 3 counts at once?
private static int[] getCounts(Scanner input) {
int[] counts = new int[3];
while(input.hasNextLine()){
String line = input.nextLine();
counts[0]++; // lines
counts[2]+=line.length(); //chars
//count words
//for simplicity make a new scanner could probably be better
//using regex or StringTokenizer
try(Scanner wordScanner = new Scanner(line)){
while (wordScanner.hasNext()) {
wordScanner.next();
count[1] ++; //words
}
}
}
return counts;
}
Of course the Object Oriented way would be to return a new object named something like Counts with methods to getNumLines(), getNumChars() etc.
EDIT
One thing to note, I kept the calculations the same as you had in the original question. I'm not sure if the counts will always be accurate especially characters since Scanner may not return all end of line characters so the chars count may be off and the number of lines may be off if there are consecutive blank lines? You would need to test this.
No it is not possible because as the documentation says
void close()
throws IOException
Closes this stream and releases any system resources associated with
it. If the stream is already closed then invoking this method has no
effect.
Once a resource is relaesed there is no way to get it back, untill you have a reference to it , which is actually closed

Converting String[] args. to int/double in java?

I'm trying to convert a main programs "String[] args" into 5 ints, and 4 doubles. (i know it's kind of confusing)
The way i was thinking of doing it was having a forreach loop to loop through String args[] and add them to an int array (for the first 5), however i had to use for the array, so it doesn't work.
if (args != null) {
// If arguments where given, use the arguments and run the program
// NEED TO SOMEHOW CONVERT ARGS INTO INTEGER FORM AFTER BEING PASSED IN
ArrayList<Integer> valArr = new ArrayList<Integer>(10); // could be 9
for (String val : args) {
// Parse the string and add it to valArray
int temp = Integer.parseInt(val);
valArr.add(temp);
}
CarPark cp = new CarPark(valArr[0], valArr[1], valArr[2], valArr[3]);
this is what i'm looking at at the moment... am i completely wrong? or close?
Just parse it with two indexing for loops.
int[] myInts = new int[5];
double[] myDoubles = new double[4];
// Initialize these arrays with "defaults" here.
// Notice how we handle the possibility of the user not entering enough values.
for (int i = 0; i < Math.min(5, args.length); i++)
myInts[i] = Integer.parseInt(args[i]);
for (int i = 0; i < Math.min(4, args.length - 5); i++)
myDoubles[i] = Double.parseDouble(args[i+5]);
CarPark cp = new CarPark(myInts[0], myInts[1], myInts[2], myInts[3]);
you have to get the values from the array list as given below
CarPark cp = new CarPark(valArr.get(0), valArr.get(1), valArr.get(2), valArr.get(3));
look at ArrayList Doc
above could be like this
CarPark cp = new CarPark(valArr.get(0), valArr.get(1), valArr.get(2), valArr.get(3));
I think this should work.
if (args != null) {
// If arguments where given, use the arguments and run the program
// NEED TO SOMEHOW CONVERT ARGS INTO INTEGER FORM AFTER BEING PASSED IN
ArrayList<Integer> valArr = new ArrayList<Integer>(10); // could be 9
for (String val : args) {
// Parse the string and add it to valArray
int temp = Integer.parseInt(val);
valArr.add(temp);
}
CarPark cp = new CarPark(valArr.get(0), valArr.get(1), valArr.get(2), valArr.get(3));
Here is your corrected code:-
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
args=new String[4];
for(int i=0;i<4;i++){
System.out.println("Enter value no- "+(i+1));
args[i]=sc.nextLine();
}
ArrayList<Integer> valArr = new ArrayList<Integer>(10);
if (args != null) {
// If arguments where given, use the arguments and run the program
// NEED TO SOMEHOW CONVERT ARGS INTO INTEGER FORM AFTER BEING PASSED IN
// could be 9
for (String val : args) {
// Parse the string and add it to valArray
int temp = Integer.parseInt(val.trim());
valArr.add(temp);
}
}
System.out.println(valArr);
//CarPark cp = new CarPark(valArr[0], valArr[1], valArr[2], valArr[3]);
}
}
This is just the code for Integer part in similar way you can extend the args array length and include double values, Remeber to use val.trim() to remove whitespaces otherwise it will throw NumberFormatException.

Scanner NextInt() using a comma separated coordinate

I am trying to parse information from a text file in the following format:
WarningGeotask: 0, 1
The first word is a keyword for a certain object to create at the coordinate location given in the numbers that follow it. Here is what my loop looks like currently:
// Open file and scan for a line
File f = new File("Simulation.Configuration");
Scanner s = new Scanner(f);
while (s.hasNextLine()) {
// Parse each line with a temporary scanner
String line = s.nextLine();
Scanner s2 = new Scanner(line);
// Get keywords from the file to match to variable names
String keyword = s2.next();
//...Multiple if statements searching for different keywords...
else if (keyword.equals("WarningGeotask:")) {
int xCoord = s2.nextInt();
int yCoord = s2.nextInt();
WarningGeotask warningGeotask = new WarningGeotask(xCoord, yCoord);
s2.close();
continue;
}
}
However, this code doesn't work properly. In fact, String xCoord = s2.nextInt() throws an error. I can do s2.next() and print out s2.nextInt() which returns 1. But I'm not sure what I'm doing wrong with Scanner to get 0 and 1 set to two different variables. Thanks for the help!
EDIT: The String variables xCoord and yCoord are supposed to be int - my fault.
The thing is that Scanner#nextInt() returns a numerical value (to be exact: a value of type int), which you try to assign to a String variable.
So instead of:
String xCoord = s2.nextInt();
String yCoord = s2.nextInt();
try:
int x = s2.nextInt();
int y = s2.nextInt();
You can do this using split()
when you read the lines, make it as Comma-separated value :
while (s.hasNextLine()) {
String line = s.nextLine().replace(":",",");
String[] data =line.split(",");
//...Multiple if statements searching for different keywords
else if(data[0].equals("WarningGeotask:")){
WarningGeotask warningGeotask = new WarningGeotask(Integer.parseInt(data[1].trim()), Integer.parseInt[data[2].trim());
}
try this
sc.useDelimiter("\\D+");
int n1 = sc.nextInt();
int n2 = sc.nextInt();

Error in Calculating sum of particular column

i am here with another problem in my code since i am new to java. my task is to read a text file that contains some 300 records and record has 13 fields . i am trying to calculate the sum of each field for example, if age is my first field them sum of the age of all 300 people and then store it in an array index.
import java.io.*;
import java.util.Vector;
public class Mean
{
private static Vector contents;
private static BufferedReader br;
private static FileInputStream inputstream;
private static FileOutputStream outputstream;
public Mean()
{
contents = new Vector();
}
public void doDuplicationRemoval(String filename)
{
try{
inputstream = new FileInputStream(filename);
br = new BufferedReader(new InputStreamReader(inputstream));
String string = "";
while((string = br.readLine())!= null)
{
String[] split = string.split(",");
Vector vector = new Vector();
for(int i=0; i<split.length; i++)
vector.add(split[i].trim());
if(!vector.contains("?"))
{
contents.add(split);
}
}
}
catch(Exception err){
System.out.println(err);
}
}
public void doDataConv(String filename)
{
DataConversion.readFile(contents);
DataConversion.writeFile(filename);
}
public static void doDataConversion(Vector contents)
{
DataConversion.readFile(contents);
for(int i=0; i<contents.size(); i++)
{
String string = "";
String[] split = (String[])contents.get(i);
split[0] += getAge(split[0]);
System.out.println(split[0]);
}
}
private static String getAge(String src)
{
String age = src;
return age;
}
public static void main(String [] args) {
Mean dr;
dr = new Mean();
dr.doDuplicationRemoval("input.txt");
dr.doDataConv("inp_out.txt");
dr.doDataConversion(contents);
}
}
the input is
63
67
50
my aim is to get output as 180
but am getting
6363
6767
5050
can someone help me to fix the problem.
This looks like the first problem to me:
private static String getAge(String src)
{
String age = src;
return age;
}
You're treating the age as a string. If you want to treat it as a number, you should be parsing it (e.g. with Integer.parseInt).
Here's the second problem:
String string = "";
String[] split = (String[])contents.get(i);
split[0] += getAge(split[0]);
System.out.println(split[0]);
That's only ever changing the value of split[0], which is then overwritten when you reassign it in the next iteration. You need something like:
int sum = 0;
for(int i=0; i<contents.size(); i++)
{
String[] split = (String[])contents.get(i);
sum += getAge(split[0]); // After changing getAge to return an int
}
System.out.println(sum);
Your not adding numbers but concatenating Strings:
split[0] += getAge(split[0]);
To sum up the values (e.g. the numeric content of your first column fields)
Define a local variable, like int sum = 0; outside the loop
parse the values from the Strings (Integer.parseInt(split[0])) and
add every parsed value to sum.
The problem is you line
split[0] += getAge(split[0]);
As the type of your split table is String, it will concatenate the values. You need a result table, like:
int[] result = new int[];
And then:
result[0] += getAge(split[0]);
I will try to formulate a good design for your purpose:
Create a class with the structure of a record. Let's name it Record
Instanciate a Record object with each line you read
Put in a Record table
You can create another Record with all the sums
Don't use Vector. If you need a list, use ArrayList (except in a multithreaded context). Vector is just a legacy class from before Java 2. It's obsolete.
your actual error is here as you are using + to add two string which contains integer
split[0] += getAge(split[0]);//here split[0] is String 63, getAge(split[0])
//retuns also String 63 hence addition gives "63" + "63" = "6363"
doing string addition that is concatenation
Integer.parseInt()
so make conversion as follow:
split[0] = new Integer (Integer.parseInt(split[0]) +
Integer.parseInt( getAge(split[0]))).toString()
if you want to store values in integer array then make another array of integer to store values.
if you want to store result in int array then do as follow:
int agesum[] = new int[]
agesum[0] += Integer.parseInt( getAge(split[0]));

Categories

Resources