Read from textfile and store into an array (JAVA) [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
public static Student[] getInput(Scanner scanner)throws FileNotFoundException
{
//change the array size by reading the input file
Student[] classList=new Student[10];
int i;
int numberOfStudents = scanner.nextInt();
while(scanner.hasNext())
{
while(numberOfStudents > classList.length)
{
//enlargeList(classList[i]);
}
for(i = 0; i <= classList.length; i++){
String studentId = scanner.nextLine();
int mark = scanner.nextInt();
classList[i] = new Student(studentId, mark);
}
}
return classList;
}
public static void main(String[] args)
{
if (args.length!=1)
{
System.out.println("Usage GradeManager inputFileName");
System.exit(1);
}
Scanner inFile=null;
try{
//do the whole try block in the lab
String fileName = args[0];
//Open a file with FileName and creaste a scanner using it
inFile = new Scanner(new File(fileName));
Student[] classList=getInput(inFile);
}
catch (FileNotFoundException fe)
{
fe.printStackTrace();
}catch(Exception e)
{
e.printStackTrace();
}finally{
if(inFile!=null)
inFile.close();
}
}
So I am trying read from a textfile that is as follows:
9
V0012345 98
V0023456 33
V0024615 51
V0089546 57
V0015348 61
V0054162 69
V0044532 87
V0031597 74
V0074615 78
First line is the number of students in the text file, all others are student number + their grade in the class. I'm trying to import these into the array classList[]. I am very new to java and object oriented stuff, so I'm sorry in advance if my code is garbage. I have omitted the enlargeList method as it works and I've tested it.
Thanks

String studentId = scanner.nextLine();
will read V0012345 98 and then
int mark = scanner.nextInt();
will read V0023456 33 and fail
try:
String line = scanner.nextLine();
//this will ignore empty lines
if(line.equals("")) continue;
String[] lineArray = line.split(" ");
String studentId = lineArray[0];
int mark = Integer.parseInt(lineArray[1]);

There are at least four problems I can see...
First, int numberOfStudents = scanner.nextInt(); won't consume the new line character, this means the next time you try and read something from the scanner, you may get the new line character (if you're reading text) or an exception of you're reading a numeric value.
Try adding scanner.nextLine() after it, for example...
int numberOfStudents = scanner.nextInt();
scanner.nextLine();
You're pre-initializing the array before you know the number of possible lines. This seems weird to me. You know ahead of time how many lines you will need to read, why not use it?
int numberOfStudents = scanner.nextInt();
scanner.nextLine();
Student[] classList = new Student[numberOfStudents];
Next, when reading the student data, you seem to be reading the entire line, the looking for an int value after it...
This would mean you are reading V0012345 98 using scanner.nextLine(), but the next call to scanner.nextInt() will encounter V0023456, which isn't a valid int value.
Instead, read the next line and create a new Scanner to parse it...
Scanner scanLine = new Scanner(line);
String studentId = scanLine.next();
int mark = scanLine.nextInt();
This is just one possible means for doing this, but I wanted to stick with the Scanner usage simply because you seem comfortable with it...
Now, somewhere in your compound loops, something gets messed up and the Scanner is getting out of sync.
Now, because we've initialised our array to the header information we read first, we can remove the compound loop in favor of something like...
while (scanner.hasNextLine() && classList.length < i) {
String line = scanner.nextLine();
Scanner scanLine = new Scanner(line);
String studentId = scanLine.next();
int mark = scanLine.nextInt();
scanLine.close();
classList[i] = new Student(studentId, mark);
i++;
}
Instead. I've left the array length check in just in case the file is lying. This means that the header can report just about any value it wants, but the loop will check for the availability of data in the file AND that we have room to read it...
This all assumes that there are no blank lines in the file you are trying to read, unlike the example you posted. If there is, you would need to add a check in and skip those lines

Related

Read from text file, then assign values to an array [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
My class project is to prompt the user for a file, that file name they input must be correct, once file is established, the first line of the file is the size of the array. Then, I have to assign each value, line by line, to the array.
Quick note** We haven't learned about buffered reader yet so I can't use that. I also can't use ArrayList, also haven't covered that yet.
Question: How do I make sure the file name they input is right? So far in class we've used while loops to check, but I'm wondering if there's a better way. I need the user to enter "investments.txt" otherwise I need to prompt them again and again. Also any points on improving existing code is very appreciated, I'm very new to this.
Code so far:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class Prog07_InvestmentManager {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Please enter the file name to import. Example: Investments.txt."); //prompt user
File file = new File(in.nextLine());
try {
Scanner inFile = new Scanner(new FileReader("investments.txt"));
double min = Integer.MAX_VALUE;
double max = 0;
double mean = 0;
int num = inFile.nextInt();
inFile.nextLine();
double line = 0;
int sum = 0;
int count = 0;
while (inFile.hasNextLine()) {
line=inFile.nextDouble();
sum+=line;
count++;
if(line>max)
max=line;
if(line<min)
min=line;
}
mean = (sum/count);
System.out.println("Max: "+max);
System.out.println("Min: "+min);
System.out.println("Mean: "+mean);
System.out.println();
} catch (FileNotFoundException e1) {
}
if (in.hasNextDouble()) {
double[] values = new double [(int) in.nextDouble()];
}
try {
Scanner inputFile = new Scanner(file);
double[] arr = new double[(int) in.nextDouble()];
for (int i = 0; in.hasNextDouble(); i++) {
arr[i] = in.nextDouble();
}
} catch (FileNotFoundException e) {
file = new File("investments.txt");
System.out.print("File not found.\nPlease enter the correct path if needed.");
file = new File(in.nextLine());
}
in.close();
}
}
So there are a couple issues with your code:
After you read in your file name, you should be done with the 'in' scanner for now. You are attempting to start reading your data from System.in which will cause your program to hang unless you manually enter all of your data.
You never overwrite your original file variable with the String from System.in. You don't even necessarily need the default value to begin with.
Just remove File file = new File("investments");
and String fileName = in.nextLine();
Then add File file = new File(in.nextLine()); after your prompt.
Your while loop outside of the try/catch is also problematic and can be deleted completely. Again, you're trying to read all of your data from System.in.
You're mismatching hasNextDouble() and .nextLine(). This works with your current setup because each number is on a new line, but in general you should use the same data type.
In general, you can read in an array of doubles from a file using the following:
Scanner scanner = new Scanner(file);
double arr = new double[scanner.nextInt()];
for(int i = 0; scanner.hasNextDouble(); i++) {
arr[i] = scanner.nextDouble();
}
scanner.close();
First suggestion is to use the List<> interface, instead of a primitive array
List<Double> value = new ArrayList<>();
1 & 2 Can be done easily by sorting the list, the first and last element will be the min and max respectively.
After that, it is just a matter or using a foreach loop to find the other values
for (Double element : value) {
// do math
}

Using Scanner and Arrays's to add BigInts

This is a project from school, but i'm only asking for help in the logic on one small part of it. I got most of it figured out.
I'm being given a file with lines of string integers, for example:
1234 123
12 153 23
1234
I am to read each line, compute the sum, and then go to the next one to produce this:
1357
188
1234
I'm stuck on the scanner part.
public static void doTheThing(Scanner input) {
int[] result = new int[MAX_DIGITS];
while(input.hasNextLine()) {
String line = input.nextLine();
Scanner linesc = new Scanner(line);
while(linesc.hasNext()) {
String currentLine = linesc.next();
int[] currentArray = convertArray(stringToArray(currentLine));
result = addInt(result, currentArray);
}
result = new int[MAX_DIGITS];
}
}
In a nutshell, I want to grab each big integer, put it an array of numbers, add them, and then i'll do the rest later.
What this is doing it's basically reading all the lines and adding everything and putting it into a single array.
What i'm stuck on is how do I read each line, add, reset the value to 0, and then read the next line? I've been at this for hours and i'm mind stumped.
Edit 01: I realize now that I should be using another scanner to read each line, but now i'm getting an error that looks like an infinite loop?
Edit 02: Ok, so after more hints and advice, I'm past that error, but now it's doing exactly what the original problem is.
Final Edit: Heh....fixed it. I was forgetting to reset the value to "0" before printing each value. So it makes sense that it was adding all of the values.
Yay....coding is fun....
hasNext method of the Scanner class can be used to check if there is any data available in stream or not. Accordingly, next method used to retrieve next continuous sequence of characters without white space characters. Here use of the hasNext method as condition of if doesn't make any sense as what you want is to check if the there are any numerical data left in the current line. You can use next(String pattern).
In addition, you can try this solution even though it is not optimal solution...
// In a loop
String line = input.nextLine(); //return entire line & descard newline character.
String naw[] = line.split(" "); //split line into sub strings.
/*naw contains numbers of the current line in form of string array.
Now you can perfom your logic after converting string to int.*/
I would also like to mention that it can easily & efficiently be done using java-8 streams.
An easier approach would be to abandon the Scanner altogether, let java.nio.io.Files to the reading for you and then just handle each line:
Files.lines(Paths.get("/path/to/my/file.txt"))
.map(s -> Arrays.stream(s.split("\\s+")).mapToInt(Integer::parseInt).sum())
.forEach(System.out::println);
If i were you i would be using the BufferedReader insted of the Scanner like this:
BufferedReader br = new BufferedReader(new FileReader("path"));
String line = "";
while((line = br.readLine()) != null)
{
int sum = 0;
String[] arr = line.split(" ");
for(String num : arr)
{
sum += Integer.parseInt(num);
}
System.out.println(sum);
}
Considering the level you're on, I think you should consider this solution. By using only the scanner, you can split the lines into an array of tokens, then iterate and sum the tokens by parsing them and validating that they're not empty.
import java.util.*;
class SumLines {
public static void main(String[] args) {
Scanner S = new Scanner(System.in);
while(S.hasNext()) {
String[] tokens = S.nextLine().split(" ");
int sum = 0;
for(int i = 0; i < tokens.length; i++) {
if(!tokens[i].equals("")) sum += Integer.parseInt(tokens[i]);
}
System.out.println(sum);
}
}
}

How to pull int value from text file of strings and ints?

I'm trying to write a program that is practically a stack. Given a text file with certain keywords, I want my program to evaluate the text line by line and perform the requested action to the stack.
For example, if the input file is:
push 10
push 20
push 30
The resulting stack should look like:
30
20
10
However, I don't know how to push these values into the stack without hardcoding an int value after the word push. I made a String variable and assigned it to scanner.nextLine()
From there, I compare the line with strLine: if strLine is equal to push followed by some Number, then that number would be pushed on the stack.
However, it seems that the method nextInt() isn't taking this number from the input stream.
Scanner input = new Scanner(file)
int number;
String strLine;
while (input.hasNextLine()){
strLine = input.nextLine();
number = input.nextInt();
if(strLine.equals("push " + number)){
stack.push(number);
}
How can I fix this?
Thank you.
Get the input and split it with space " "!
That will give ["push","1"]
convert the first index to int and then push the value to stack!
while (input.hasNextLine()){
String[] strLine = input.nextLine().split(" ");
if(strLine[0].equals("push")){
stack.push(Integer.parseInt(strLine[1]));
}
else if(strLine[0].equals("pop")){
stack.pop();
}
else{
system.out.println("Please enter a valid input!");
}
}
Hope it helps!
input.nextLine reads the whole line, including the number. What you can do instead is to use input.next() to get the "push" and input.nextInt() to get the number. This example is using Scanner with System.in (so it needs "quit" to exit the while loop), but it should also work with a file (in which case you don't need to type "quit" to exit the program, as it will do so automatically when the input file has no more input). The advantage of using parseInt (as some of the other answers have suggested) is that you can catch any errors in integer input using a try/catch block.
import java.util.Scanner;
import java.util.Stack;
import java.util.InputMismatchException;
public class StackScanner {
public static void main(String args[]) {
Stack<Integer> stack = new Stack<Integer>();
Scanner input = new Scanner(System.in);
int number;
String strLine;
while (input.hasNext()){
strLine = input.next();
if(strLine.equals("push")){
try {
number = input.nextInt();
stack.push(number);
} catch ( InputMismatchException e) {
System.out.println("Invalid input. Try again.");
input.nextLine();
continue;
}
} else {
break;
}
}
System.out.println(stack);
}
}
Sample output:
push 5
push 6
push 3
quit
[5, 6, 3]
change this:
number = input.nextInt();
to this:
number = Integer.parseInt(input.nextLine());
nextLine method parses the whole line including any numbers in the line. So, you need to take care of splitting the line and parsing the number in your code.
Something like below will work where I split the line with spaces. Although, there are many such ways possible.
Scanner input = new Scanner(file);
String strLine;
Stack<Integer> stack = new Stack<>();
int number;
while (input.hasNextLine()){
strLine = input.nextLine();
if(strLine.startsWith("push")){
String[] sArr = strLine.split("\\s+");
System.out.println(strLine);
if(sArr.length==2){
number=Integer.parseInt(sArr[1]);
stack.push(number);
System.out.println(number);
}
}
}
If I understand your problem, I would simply tokenize the line by splitting on whitespace.
It looks like your input is relatively structured: you have a keyword of some kind then whitespace then a number. If your data is indeed of this structure, split the line into two tokens. Read the value from the second one. For example:
String tokens[] = strLine.split(" ");
// tokens[0] is the keyword, tokens[1] is the value
if(tokens[0].equals("push")){
// TODO: check here that tokens[1] is an int
stack.push(Integer.parseInt(tokens[1]));
} else if (tokens[0].equals("pop")) { // maybe you also have pop
int p = stack.pop();
} else if ... // maybe you have other operations

reading 3 integers in one line java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
help me finding a way to read from user 3 integers in one line and then treat each saparately as a,b,c .. please be quick because i had tried reading a whole line but i want to deal with each integer in later statement
import java.util.Scanner;
public class MHDKhaledTotonji_301300797 {
public static void main(String[] args){
Scanner input=new Scanner(System.in);
int M,a,b,c;
System.out.println("Please, insert the normal dose in ml");
M = input.nextLine();
}
}
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
int c = in.nextInt();
takes: 1 2 3
nextLine() returns a String, so M should be defined as a String.
Java naming conventions generally state that variables should start with lowercase letter, so M should be m.
As for the task of getting 3 integers from the user on one line, you have multiple choices, and it depends on how strict you want to be and how much error handling you need.
For very easy solution, with no error handling (kills program on bad input), Scanner is the answer. Error handling can be added, but is cumbersome.
Scanner in = new Scanner(System.in);
System.out.println("Please, insert the normal dose in ml");
int a = input.nextInt();
int b = input.nextInt();
int c = input.nextInt();
Another solution might be to read the line, like you are trying to do, then split the line and parse the values. A little more code, but forces user to enter all 3 on one line, which solution #1 doesn't.
Scanner in = new Scanner(System.in);
System.out.println("Please, insert the normal dose in ml");
String line = input.nextLine();
String[] values = line.split(" ");
int a = Integer.parseInt(values[0]);
int b = Integer.parseInt(values[1]);
int c = Integer.parseInt(values[2]);
For better control of the line from the user, a regular expression can be used. Here it is with full error handling.
Scanner in = new Scanner(System.in);
Pattern p = Pattern.compile("\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*");
int a = 0, b = 0, c = 0;
for (;;) {
System.out.println("Please, insert the normal dose in ml");
String line = input.nextLine();
Matcher m = p.matcher(line);
if (m.matches())
try {
a = Integer.parseInt(m.group(1));
b = Integer.parseInt(m.group(2));
c = Integer.parseInt(m.group(3));
break;
} catch (Exception e) {/*fall thru to print error message*/}
System.out.println("** Bad input. Type 3 numbers on one line, separated by space");
}
use input.nextInt() instead of input.nextLine(). Also this is wrong because input.nextLine() returns String and you should parse to integer.
Simple change your code to:
M = input.nextInt();
a = input.nextInt();
b = input.nextInt();
c = input.nextInt();
Stick in mind that input.nextInt() ignores every white space including line feeds so you don't need to worry about reading from the same or different lines.

Is there a way to read and calculate data from a file in Java using methods?

In my class we're using methods to calculate data from a text file. If I had a file that looked exactly like this:
Bob
25
Molly
30
Dylan
10
Mike
65
Is there anyway to pull this data from a file and then send it to a method to calculate, and then return that calculation to display on main? I'm confused as to how Java would be able to skip each line and calculate the numbers instead of the persons name. I was thinking about using inputFile.nextDouble(); and inputFile.nextLine();. But how would I be able to set a String read the lines in the text file if I'm supposed to readthose text file lines variables as doubles? Sorry for all of the questions, I've been stuck on this for a long time and it's driving me crazy >.
You should just alternately use nextLine() and nextInt()
Scanner sc=new Scanner(new File(/* Path to the file*/));
int i=0;
while(sc.hasNext())
{
if(i==0)
{
name=sc.nextLine();
}
else
{
number=sc.nextInt();
}
i=1-i;
}
I recommend you to use an ArrayList to read the full file:
Scanner s = new Scanner(new File(//Here the path of your file));
int number;
String name;
ArrayList<String> list = new ArrayList<String>();
while (s.hasNext())
{
list.add(s.nextLine());
}
Now you have all the lines of your file (as a String) so now you can operate with the full data that it's inside.
Further, the numbers are in the even lines so you can use a loop to through all the lines and check if the line that you are using now it's even or not.
for(int i = 0; i < list.size(); i++)
{
if(i%2 == 0)
{
number = Integer.parseInt(list.get(i));
//You can use the references to your methods with this number
}
else
{
name = list.get(i);
}
}
With the % you will get the rest of the division (I'm using a property of pairs numbers). With Integer.parseInt you will parse your String to int.
So now you will be able to use this numbers to operate or whatever you want.
EDIT: Here you have an example without using ArrayList. In this case I'm going to use nextLine() and nextInt() functions:
Scanner s = new Scanner(new File(//Here the path of your file));
int count = 0;
int number;
int name;
while(s.hasNext())
{
if(i%2 == 0)
{
number = s.nextInt();
s.nextLine();
//You can use the references to your methods with this number
}
else
{
name = s.nextLine();
}
count = count + 1;
}
If you have doubts about why I'm using s.nextLine() after number without storing any value you can look my answer to this question: Why isn't the scanner input working?
I expect it will be helpful for you!

Categories

Resources