Contents of array being overwritten [duplicate] - java

This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 6 years ago.
Please forgive me as I am new to all this.
My code reads a text file of numbers and names. 3 sets of numbers after each name, each set of 3 gets put into an array. When the array gets sent to another class in the loop, the contents of the array becomes overwritten, I am assuming because it is just referencing the address of the array, not the actual values.
public void readMarksData(String fileName) throws FileNotFoundException
{
File dataFile = new File(fileName);
Scanner scanner = new Scanner(dataFile);
int[] marks = new int[3];
scanner.nextLine();
int i = 0;
while( scanner.hasNext() )
{
String studentName = scanner.nextLine();
while(i < 3)
{
try
{
marks[i] = scanner.nextInt();
i++;
}
catch ( InputMismatchException ex )
{
i=0;
}
}
scanner.nextLine();
storeStudentRecord(studentName, marks);
//scanner.nextLine();
i=0;
}
scanner.close();
}
Code for storing values in another class
private void storeStudentRecord(String name, int[] marks)
{
//int[] x = new int[3]
StudentRecord student = new StudentRecord(name, marks);
marksList.add(student);
}
Constructor method in other class
public StudentRecord(String nameInput, int[] marksInput)
{
// initialise instance variables
name = nameInput;
noOfMarks = 0;
marks = marksInput;
}
This has been driving me nuts for hours so any help would be greatly greatly appreciated, thank you.

You could modify the constructor so that it creates a copy of the array and uses it :
public StudentRecord(String nameInput, int[] marksInput)
{
// initialise instance variables
name = nameInput;
noOfMarks = 0;
if(marksInput!=null)
marks = Arrays.copyOf(marksInput, marksInput.length);
else
marks = null;
}

Related

Issue with scanner in main method vs in constructor java?

SOLVED
I'm having an issue using Scanners nextInt() method in a class constructor.
it works fine if used in a main method like the code below however when doing the same thing in a constructor I get an inputmismatchexception,
what could be the possible issues?
public class QuickTest{
public static void main(String[] args) throws Exception{
java.io.File myFile = new java.io.File("tograph.txt");
java.util.Scanner input = new java.util.Scanner(myFile);
int numberOfPoints = input.nextInt();
String[] myArray = new String[numberOfPoints];
//need to use nextLine once after reading in number of points to get to next line
input.nextLine();
int count = 0;
while(input.hasNext() == true){
myArray[count] = input.nextLine();
count++;
}
input.close();
for(int i = 0; i < myArray.length; i++){
System.out.println(myArray[i]);
}
the class version
public class MyGraph{
//filled with strings from file
String[] points;
java.io.File file;
java.util.Scanner input;
//length of points array
int numPoints;
public MyGraph(String file){
this.file = new java.io.File(file);
this.input = new java.util.Scanner(file);
this.numPoints = this.input.nextInt();
this.points = new String[this.numPoints];
fillGraphArray();
}
//after getting the number of vertices we populate the array with every
//line after those points untill the end
private void fillGraphArray(){
//used once after reading nextInt()
this.input.nextLine();
int count = 0;
while(this.input.hasNext() == true){
points[count] = input.nextLine();
count++;
}
input.close();
}
//test method to be delted later
public String[] getPoints(){
return this.points;
}
//may need a method to close the file
}
When I use the debugger the main method version will get the number of points from the file and then fill the array with a string from each following line in the file however the class version throws the exception

read lines from external file and store elements in array

I am new here so please show some patience. I am trying to read the data from an external file and store the info in 2 arrays.
The file looks like this:
0069 723.50
0085 1500.00
0091 8237.31
I am using 2 scanners to read the input and I think they work ok because when I try to print, the result looks ok.
My first problem is that I am able to read the first numbers on the list using nextInt(), but cannot use nextDouble() for the double ones as I get the "java.util.InputMismatchException" message. For that reason I read it as a String. The part with the other two scanners is supposed to do what the first parts should do, for a different input file, but the problem is the same.
My next and biggest problem, until now, is that am not able to store the values from the two columns in two distinct arrays. I have tried several ways (all commented) but all fail. Please help and thanks.
Here is my code:
import ui.UserInterfaceFactory;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Scanner;
import ui.UIAuxiliaryMethods;
public class Bank {
static final int MAX_NUMBER_OF_ACCOUNTS = 50;
PrintStream out;
Bank(){
UserInterfaceFactory.enableLowResolution(true);
out = new PrintStream(System.out);
}
void readFiles(){
Scanner balanceFile = UIAuxiliaryMethods.askUserForInput().getScanner();
while(balanceFile.hasNextLine()){
String balance_Line = balanceFile.nextLine();
Scanner accountsFile = new Scanner(balance_Line);
int account = accountsFile.nextInt(); //works
out.printf("%04d ",account);
/*int [] accounts_array = new int [MAX_NUMBER_OF_ACCOUNTS]; //does not store the values properly
int account = accountsFile.nextInt();
for(int j=0; j < accounts_array.length; j++){
accounts_array[j] = account;
}*/
/*int [] accounts_array = new int [MAX_NUMBER_OF_ACCOUNTS]; //java.util.InputMismatchException
for(int j=0; j < accounts_array.length; j++){
accounts_array[j] = accountsFile.nextInt();
//out.printf("%04d \n",accounts_array[j]);
}*/
String balance = accountsFile.nextLine(); //problem declaring balance as a double
out.printf("%s\n",balance);
/*String [] balance_array = new String [MAX_NUMBER_OF_ACCOUNTS]; //java.util.NoSuchElementException
for(int j=0; j < balance_array.length; j++){
accountsFile.useDelimiter(" ");
balance_array[j] = accountsFile.next();
//out.printf("%04d \n",accounts_array[j]);
}*/
}
Scanner mutationsFile = UIAuxiliaryMethods.askUserForInput().getScanner();
while(mutationsFile.hasNext()){
String mutation_Line = mutationsFile.nextLine();
Scanner mutatedAccountsFile = new Scanner(mutation_Line);
int mutated_account = mutatedAccountsFile.nextInt();
out.printf("%04d ",mutated_account);
int action = mutatedAccountsFile.nextInt(); //deposit or withdrawal
/*if (action == 1){
}else{
}*/
out.printf(" %d ",action);
/*Double amount = mutatedAccountsFile.nextDouble();
out.printf(" %5.2f ",amount);*/
String amount = mutatedAccountsFile.nextLine();
out.printf("%s\n",amount);
}
}
void start(){
new Bank();readFiles();
}
public static void main(String[] args) {
new Bank().start();
}
}
The InputMismatchException occurs because you try to read a double using the nextInt() function. To solve this issue, you can first read the tokens as Strings using the next() function and convert them appropriately.
while(mutationsFile.hasNext()){
mutation_Line = mutationsFile.next();
if(mutation_Line.indexOf(".") == -1)
//token is int
else
//token is double
}
Since you already know what the contents of the two columns are, you can store the integers and doubles in two lists and then, if you want, get them into an array.
List<Integer> intList = new ArrayList<Integer>();
List<Double> doubleList = new ArrayList<Double>();
Now replace the if statements in the first snippet with this:
if(mutation_Line.indexOf(".") == -1)
intList.add(new Integer(Integer.parseInt(mutation_Line)));
else
doubleList.add(new Double(Double.parseDouble(mutation_Line)));
In the end, you can get them into arrays:
Object[] intArr = intList.toArray(),
doubleArr = doubleList.toArray();
//display the contents:
for(int i=0; i<intArr.length; i++)
out.printf("%04d\t%.2f\n", Integer.parseInt(intArr[i].toString()),
Double.parseDouble(doubleArr[i].toString()));
OUTPUT:
0069 723.50
0085 1500.00
0091 8237.31
First off, you don't need to use 2 scanners. The Scanner object is simply reading your file, one scanner is plenty to accomplish the task of reading a file.
If you're trying to read the integers/doubles from file and are having trouble with nextInt() and nextDouble(), consider a different approach to parsing (e.g. parse the line into a string, split the line into 2 parts based on a space character, then trim both resulting strings and convert to respective integers/doubles).
Now back to the Scanner parsing the two values, remember first that when you use a next() or nextInt(), etc. those methods consume the next respective token. So parsing a line as a string from the file into another Scanner object is redundant and unnecessary in this case.
If you know your max number of accounts, and it's simply 50, then go ahead an allocate that prior to the while loop.
Here's an alternative approach with the code you posted.
public class App {
static int MAX_NUMBER_OF_ACCOUNTS = 50;
static PrintStream out;
static void readFiles() {
Scanner balanceFile = null;
try {
balanceFile = new Scanner(new File("C:\\Users\\Nick\\Desktop\\test.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (balanceFile == null)
return;
int [] accounts_array = new int [MAX_NUMBER_OF_ACCOUNTS];
double [] balance_array = new double [MAX_NUMBER_OF_ACCOUNTS];
int currentIndex = 0;
while (balanceFile.hasNextLine()) {
int account = balanceFile.nextInt();
double balance = balanceFile.nextDouble();
System.out.print("acc = " + account + " ");
System.out.println("bal = " + balance);
//out.printf("%04d ", account);
accounts_array[currentIndex] = account;
//out.printf("%s\n", balance);
balance_array[currentIndex] = balance;
currentIndex++;
}
balanceFile.close();
}
static void start() {
readFiles();
}
public static void main(String[] args) {
start();
}
}
Please note the excessive use of static could also be avoided in the future, but for the sake of the example it spread like the plague.
As you can see in the logic leading up to the while loop, the scanner object is made from a file I copied your example data into a file on my desktop. The arrays are allocated prior to the while loop (note: see #progy_rock and their use of ArrayList's - may help improve your code in the long run). And finally, note the index count to move the position along in the array to which you are inserting your lines to.

Error: NoSuchElementException when trying to read values from file to array

Okay. So this is the last HW assignment of the semester, I am leaving out a big part of the program because this is the only thing I can't seem to fix. I am setting up my FileInputStream and using a for loop to read values into the array as I have done in the past without problems. For some reason I am getting this exception and can't figure it out. I have looked at plenty of other threads around this exception but likewise, cant seem to figure it out. Please halp.
Here is the code, it compiles;
import java.util.*;
import java.io.*;
public class CollinDunn_1_10 {
// Declare constants
static final int MAX_EMPLOY = 30;
static final String TAB = "\t";
static final String NL = "\n";
static final double IRA_INVEST = .08;
static final double FEDERAL_WITH = .18;
static final double STATE_WITH = .045;
static final double SAVINGS = .10;
public static void main (String [] args) throws Exception {
// I/O String references
final String INPUT = "CollinDunn_1_10_Input.txt";
final String OUTPUT = "CollinDunn_1_10_Output.txt";
// Declare variables
// One-dimensional array for storing employee names
String [] names = new String [MAX_EMPLOY];
// Two-dimensional array for storing employee pay data
// [0] hours worked [1] pay rate [2] gross pay [3] net pay
// [4] savings amount [5] IRA amount [6] taxs withheld
double [][] payInfo = new double [MAX_EMPLOY][6];
// Set up I/O
FileInputStream inputDataFile = new FileInputStream(INPUT);
Scanner inputFile = new Scanner(inputDataFile);
FileWriter outputDataFile = new FileWriter(OUTPUT);
PrintWriter outputFile = new PrintWriter(outputDataFile);
// Read data from the file
readData(inputFile, payInfo, names);
// Test printing to see if values are stored - REMOVE
for (int i = 0; i < MAX_EMPLOY; i++) {
System.out.print(names[i] + TAB + payInfo[i][0] + TAB + payInfo[i][1]);
}
} // End main
// Method for reading file data into the file.
// Data is sorted as (number of hours) (pay rate) (name)
public static void readData (Scanner inputFile, double [][] payInfo, String [] names) {
for (int i = 0; i < MAX_EMPLOY; i++) {
payInfo [i][0] = inputFile.nextDouble();
payInfo [i][1] = inputFile.nextDouble();
names [i] = inputFile.nextLine();
} // End For
return;
} // End readData
} // End Class
*The fields on the text file are as so:
(hours) (pay) (name)
50.00 10.60 Light Karen L
52.00 10.80 Fagan Bert Todd
62.00 12.24 Antrim Forrest N*
The Exception and stack trace:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextDouble(Scanner.java:2413)
at CollinDunn_1_10.readData(CollinDunn_1_10.java:56)
at CollinDunn_1_10.main(CollinDunn_1_10.java:42)
You're never checking whether there is a value to retrieve before trying to retrieve it (look up Scanner.hasNextDouble). Since your for-loop goes through MAX_EMPLOY iterations, this exception will occur whenever your input file contains less than MAX_EMPLOY lines of data.
You should everytime check if your tables or your file contains right amounts of elements or if they are big enought. Code should look like:
public static void readData (Scanner inputFile, double [][] payInfo, String [] names) {
Integer payInfoLenght = payInfo.lenght;
Integer namesLenght = names.lenght;
if (MAX_EMPLOY > payInfoLenght || MAX_EMPLOY > namesLenght) {
System.out.println("Wrong size of tabels");
} else {
for (int i = 0; i < MAX_EMPLOY; i++) {
if (inputFile.hasNextDouble()) {
payInfo [i][0] = inputFile.nextDouble();
}
if (inputFile.hasNextDouble()) {
payInfo [i][1] = inputFile.nextDouble();
}
if (inputFile.hasNextLine()) {
names [i] = inputFile.nextLine();
}
}
}
}
And you don't need "return;" at the end of this method becouse this method nothing returns. It's "void" method.

Using standard input in java, how to input an entire array of integers? [duplicate]

This question already has answers here:
How to read array of integers from the standard input in Java?
(2 answers)
Closed 8 years ago.
So my code looks like this so far:
public class PancakeSort {
public static int flip(int n) {
int temp = 0;
for (int i = 0; i < (n+1) / 2; ++i) {
int[] pancakes = new int[n];
temp = pancakes[i];
pancakes[i] = pancakes[n-i];
pancakes[n-i] = temp;
}
return temp;
}
public static void sort (int[] pancakes) {
for (int i=0; i<pancakes.length; i++){
if (pancakes[i] > pancakes[i+1]){
flip(i+1);
}
}
System.out.println(pancakes);
}
public static void main(String[] args) {
}
}
But how I input a whole array of integers using standard input (StdIn.readLine())? I understand that the code might not be correct and I'm working on figuring that out,and I'm also aware that this question has been asked before in this site, but not specifically using the standard library and that is where I'm stuck.
You can send integer array as input
PancakeSort pancakeSort = new PancakeSort();
pancakeSort.sort(new int[] { 100, 50, 89, 2, 5, 150 });
or Use scanner class as
int arr[] = new int[10];
Scanner sc = new Scanner(System.in);
int i = 0;
while (sc.hasNextInt()) {
arr[i] = sc.nextInt();
i = i + 1;
}
PancakeSort pancakeSort = new PancakeSort();
pancakeSort.sort(arr);
But in last case you must not increased the size of array.Otherwise it will give arrayIndexOutOfBoundException
I believe you may be referencing StdIn such as a class like this one?
http://introcs.cs.princeton.edu/java/stdlib/StdIn.java.html
If so, then to get an int from the console you just call StdIn.readInt. An example of how you could approach this is:
public static void main(String[] args)
{
System.out.println("Enter number of pancakes, or enter 0 to quit");
int[] pancakeArray = new int[0];
while (true)
{
try
{
int entry = StdIn.readInt();
if (entry == 0)
{
break;
}
int[] expandedArray = new int[pancakeArray.length + 1];
System.arraycopy(pancakeArray, 0, expandedArray, 0, pancakeArray.length);
expandedArray[pancakeArray.length] = entry;
pancakeArray = expandedArray;
}
catch (Exception e)
{
System.out.println("Invalid entry detected, closing input");
break;
}
}
System.out.println("Pancake array length: " + pancakeArray.length);
sort(pancakeArray);
System.out.println("Final pancake array in order:");
for (int entry : pancakeArray)
{
System.out.println("Pancake value: " + entry);
}
}
This would read int after int until they entered 0 or an invalid value, then it would call your sort routine from there. There are issues in your sort routine but you said you wanted to look at that, so I will let you figure that part out.

getting a length of a string from a variable array java

Im a student learning Java and this is part of my program and it is supposed to get the length of a string but the strings are all in an array. I try to run this in eclipse and it says i get an error where it sayslength = name[x].length() can someone let me know if there is a way to fix this
public class GuessName
{
Random random = new Random();
Scanner scan = new Scanner(System.in);
String[] name = new String[10];
int x,length;
char guess1,guess2,guess3;
public void names()
{
name[0] = "MARK";
name[1] = "CHARLIE";
name[2] = "MEG";
name[3] = "KYLE";
name[4] = "JUSTIN";
name[5] = "KATARINA";
name[6] = "JOEL";
name[7] = "KEVIN";
name[8] = "MICHAEL";
name[9] = "JENNA";
name[10] = "GREG";
}
public void start()
{
x = random.nextInt(10);
length = name[x].length();
}
You have an array, as follows:
String[] name = new String[10];
The number between the [] represents the size of the array. In your example, your array has a size of 10 meaning your array has 10 indexes which are [0,9] (because indexes start at 0). The last line of your names() method is:
name[10] = "GREG";
Do you know where I'm getting at?
Also, what does your main method look like? If you're receiving a NullPointerException it probably means you are calling start() before names().
I commented out the parts that was problematic. Also, you are trying to initialize 11 names as opposed to 10. Please note that arrays index starts at 0. I don't know why you have scanner object in there but you can use this block to complete your code.
import java.util.Random;
import java.util.Scanner;
public class GuessName {
// Scanner scan = new Scanner(System.in);
String[] name = new String[10];
int x,length;
char guess1,guess2,guess3;
public GuessName()
{
name[0] = "MARK";
name[1] = "CHARLIE";
name[2] = "MEG";
name[3] = "KYLE";
name[4] = "JUSTIN";
name[5] = "KATARINA";
name[6] = "JOEL";
name[7] = "KEVIN";
name[8] = "MICHAEL";
name[9] = "JENNA";
// name[10] = "GREG";
}
public void start()
{
Random random = new Random();
this.x = random.nextInt(10);
this.length = name[this.x].length();
}
public static void main(String[] args) {
GuessName gn = new GuessName();
gn.start();
System.out.println("The name is: "+gn.name[gn.x]+" and the length is: "+ gn.x);
} }

Categories