Storing input from text file - java

My question is quite simple, I want to read in a text file and store the first line from the file into an integer, and every other line of the file into a multi-dimensional array. The way of which I was thinking of doing this would be of creating an if-statement and another integer and when that integer is at 0 store the line into the integer variable. Although this seems stupid and there must be a more simple way.
For example, if the contents of the text file were:
4
1 2 3 4
4 3 2 1
2 4 1 3
3 1 4 2
The first line "4", would be stored in an integer, and every other line would go into the multi-dimensional array.
public void processFile(String fileName){
int temp = 0;
int firstLine;
int[][] array;
try{
BufferedReader input = new BufferedReader(new FileReader(fileName));
String inputLine = null;
while((inputLine = input.readLine()) != null){
if(temp == 0){
firstLine = Integer.parseInt(inputLine);
}else{
// Rest goes into array;
}
temp++;
}
}catch (IOException e){
System.out.print("Error: " + e);
}
}

I'm intentionally not answering this to do it for you. Try something with:
String.split
A line that says something like array[temp-1] = new int[firstLine];
An inner for loop with another Integer.parseInt line
That should be enough to get you the rest of the way

Instead, you could store the first line of the file as an integer, and then enter a for loop where you loop over the rest of the lines of the file, storing them in arrays. This doesn't require an if, because you know that the first case happens first, and the other cases (array) happen after.

I'm going to assume that you know how to use file IO.
I'm not extremely experienced, but this is how I would think about it:
while (inputFile.hasNext())
{
//Read the number
String number = inputFile.nextLine();
if(!number.equals(" ")){
//Do what you need to do with the character here (Ex: Store into an array)
}else{
//Continue on reading the document
}
}
Good Luck.

Related

make list of integers from text file in java

Im trying to make it so based on the user inputted number, I compare that to series of numbers in a separate file and pick the numbers that are larger than the inputted number.
I have this so far:
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
while ((line = br.readLine()) != null) {
I only got it to read the file but I dont know how to do the whole "comparing" step. I figure I need to somehow define each number in the file and compare it to the users number. The text file looks like this:
1
2
3
4
5
6
7
If the user picks the number 4, I want it to print "There are 3 numbers bigger than 4" or something to that extent.
I think I need to make a list of the numbers from the file but I dont know how to do it. Im just a beginner. I just really dont know where to go from here. If there is a similar question with solution, please link it. Id appreciate any help/advice. PLease help me. TY in advance.
You could take advantage of Streams and Java 8 to solve your problem
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
long n = stream.mapToInt(Integer::valueOf)
.filter(readNumber -> readNumber > num)
.count();
System.out.println("There are " + n + " numbers in the file greater than " + num);
} catch (IOException e) {
System.out.println(e.getMessage());
}
Supposing fileName contains the name of the file and num the number the user selected, open the file using a try-with-resources and create a Stream with the lines of the file. Map the stream to a Stream of ints and then filter it to get only those values greater than num. Lastly, apply count in order to get the number of elements that satisfy the predicate and print the message.
Hope it helps.
You can use an ArrayList to store the data.
ArrayList<Integer> list = new ArrayList();
while ((line = br.readLine()) != null) {
Integer userInputAsInteger = Integer.parseInt(line);
if(userInputAsInteger > num){
list.add(userInputAsInteger );
}
}
Then you can use this list to get the number of elements larger than num:
System.out.println(list.size() + " numbers are larger then " + num);
You can also print out the numbers:
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}

Reading integers in a .txt file (Java)

So basically I'm trying to write a program where someone can enter 10 integers, that would then be saved in a .txt file, then opened and averaged together.
I'm doing pretty good so far, I got all the exception handling and saving a file with my inputted integers down, but I'm unsure how to read the file. I'm assuming calculating the average wouldn't be difficult once I have that all done anyways. Here's part of my code with the rest linked below (I really think you'd need to see the full code to better recognize the issue):
public static void closeFile()
{
if (output != null)
output.close();
}
public static void readRecords()
{
try
{
while (input.hasNext())
{
System.out.printf("%s%n", String.valueOf(numbers[i]));
}
}
}
http://pastebin.com/yW6G8N8C
You are not opening the file properly, you need to use a reader for that:
public static void readRecords(){
try (BufferedReader br = new BufferedReader(new FileReader("numbers.txt"))) {
String line;
int[] number = new int[10];
i=-1;
while ((line = br.readLine()) != null) {
i++;
number[i] = Integer.parseInt(line);
System.out.println("number "+i+" = "+number[i]);
}
}
catch(Exception e){
// Handle the trouble
}
}
I am not entirely sure what you want to do with your numbers you get or the exact format of the numbers.txt file but I am assuming you are doing something sensible, like writing one integer per line to your file. Otherwise, adjust the code accordingly to suit your needs.
First of all as mentioned by chalarangelo you are not opening the file correctly. You can use Formatter class to write to file but you can't read from file using that. So you need to use a proper reader like BufferedReader and use its readLine() method.
That aside is it necessary that you store integers together with the string
"Inputted integer: "... If so then its going to be a bit difficult to just get the numbers. I'd advise printing just numbers into the file i.e just do
output.format("%s%n", String.valueOf(numbers[i]));
instead of
output.format("Inputted integer: %s%n", String.valueOf(numbers[i]));
After that use a reader and read the line and convert it into integer and store it in the array as mentioned in chalarengo's answer.

Parse .csv File in java returns outofbounds exception

I have the following issue: I am trying to parse a .csv file in java, and store specifically 3 columns of it in a 2 Dimensional array. The Code for the method looks like this:
public static void parseFile(String filename) throws IOException{
FileReader readFile = new FileReader(filename);
BufferedReader buffer = new BufferedReader(readFile);
String line;
String[][] result = new String[10000][3];
String[] b = new String[6];
for(int i = 0; i<10000; i++){
while((line = buffer.readLine()) != null){
b = line.split(";",6);
System.out.println("ID: "+b[0]+" Title: "+b[3]+ "Description: "+b[4]); // Here is where the outofbounds exception occurs...
result[i][0] = b[0];
result[i][1] = b[3];
result[i][2] = b[4];
}
}
buffer.close();
}
I feel like I have to specify this: the .csv file is HUGE. It has 32 columns, and (almost) 10.000 entries (!).
When Parsing, I keep getting the following:
XXXXX CHUNKS OF SUCCESFULLY EXTRACTED CODE
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:3
at ParseCSV.parseFile(ParseCSV.java:24)
at ParseCSV.main(ParseCSV.java:41)
However, I realized that SOME of the stuff in the file has a strange format e.g. some of the texts inside it for instance have newlines in them, but there is no newline character involved in any way. However, if I delete those blank lines manually, the output generated (before the error message is prompted) adds the stuff to the array up until the next blank line ...
Does anyone have an idea how to fix this? Any help would be greately appreciated...
Your first problem is that you probably have at least one blank line in your csv file. You need to replace:
b = line.split(";", 6);
with
b = line.split(";");
if(b.length() < 5){
System.err.println("Warning, line has only " + b.length() +
"entries, so skipping it:\n" + line);
continue;
}
If your input can legitimately have new lines or embedded semi-colons within your entries, that is a more complex parsing problem, and you are probably better off using a third-party parsing library, as there are several very good ones.
If your input is not supposed to have new lines in it, the problem probably is \r. Windows uses \r\n to represent a new line, while most other systems just use \n. If multiple people/programs edited your text file, it is entirely possible to end up with stray \r by themselves, which are not easily handled by most parsers.
A way to easily check if that's your problem is before you split your line, do
line = line.replace("\r","").
If this is a process you are repeating many times, you might need to consider using a Scanner (or library) instead to get more efficient text processing. Otherwise, you can make do with this.
When you have new lines in your CSV file, after this line
while((line = buffer.readLine()) != null){
variable line will have not a CSV line but just some text without ;
For example, if you have file
column1;column2;column
3 value
after first iteration variable line will have
column1;column2;column
after second iteration it will have
3 value
when you call "3 value".split(";",6) it will return array with one element. and later when you call b[3] it will throw exception.
CSV format has many small things, to implement which you will spend a lot of time. This is a good article about all possible csv examples
http://en.wikipedia.org/wiki/Comma-separated_values#Basic_rules_and_examples
I would recommend to you some ready CSV parsers like this
https://commons.apache.org/proper/commons-csv/apidocs/org/apache/commons/csv/CSVParser.html
String's split(pattern, limit) method returns an array sized to the number of tokens found up to the the number specified by the limit parameter. Limit is the maximum, not the minimum number of array elements returned.
"1,2,3" split with (",", 6) with return an array of 3 elements: "1", "2" and "3".
"1,2,3,4,5,6,7" will return 6 elements: "1", "2", "3", "4", "5" and ""6,7" The last element is goofy because the split method stopped splitting after 5 and returned the rest of the source string as the sixth element.
An empty line is represented as an empty string (""). Splitting "" will return an array of 1 element, the empty string.
In your case, the string array created here
String[] b = new String[6];
and assigned to b is replaced by the the array returned by
b = line.split(";",6);
and meets it's ultimate fate at the hands of the garbage collector unseen and unloved.
Worse, in the case of the empty lines, it's replaced by a one element array, so
System.out.println("ID: "+b[0]+" Title: "+b[3]+ "Description: "+b[4]);
blows up when trying to access b[3].
Suggested solution is to either
while((line = buffer.readLine()) != null){
if (line.length() != 0)
{
b = line.split(";",6);
System.out.println("ID: "+b[0]+" Title: "+b[3]+ "Description: "+b[4]); // Here is where the outofbounds exception occurs...
...
}
or (better because the previous could trip over a malformed line)
while((line = buffer.readLine()) != null){
b = line.split(";",6);
if (b.length() == 6)
{
System.out.println("ID: "+b[0]+" Title: "+b[3]+ "Description: "+b[4]); // Here is where the outofbounds exception occurs...
...
}
You might also want to think about the for loop around the while. I don't think it's doing you any good.
while((line = buffer.readLine()) != null)
is going to read every line in the file, so
for(int i = 0; i<10000; i++){
while((line = buffer.readLine()) != null){
is going to read every line in the file the first time. Then it going to have 9999 attempts to read the file, find nothing new, and exit the while loop.
You are not protected from reading more than 10000 elements because the while loop because the while loop will read a 10001th element and overrun your array if there are more than 10000 lines in the file. Look into replacing the big array with an arraylist or vector as they will size to fit your file.
Please check b.length>0 before accessing b[].

What's an elegant way to parse this text in java?

Disclaimer:
The parsing-problem described in here is very simple. This question does not simply ask for a way to achieve the parsing. - That's almost straightforward - Instead, it asks for an elegant way. That elegant way would probably be one which does not first read line-wise and then parse each line on its own, as this is obviously not necessary. However, is this elegant way possible with ready to use standard classes?
Question:
I have to parse text of the following form in java (there is more than these 3 records; records can have way more lines than these examples):
5
Dominik 3
Markus 3 2
Reiner 1 2
Samantha 4
Thomas 3
4
Babette 1 4
Diana 3 4
Magan 2
Thomas 2 4
The first number n is the number of lines in the record directly following. Each record consists of a name and then 0 to n integers.
I thought that using java.util.Scanner is a natural choice, but it leads to the nastiness that when using hasNextInt() and hasNext() to determine if a line is started, I can't distinguish if a read number is the header of the next record or it's the last number behind the last name of the previous record. Example from above:
...
Thomas 3
4
...
Here, I don't know how to tell if the 3 and the 4 is a header or belongs to the current line of Thomas.
Sure I can first read line by line, put them into another Scanner, and then read them again, but this effectively parses the whole data twice, which looks ugly to me. Is there a better way?
I would need something like a flag which tells me if a line break was encountered during the last delimiter skipping operation.
Read the file using FileReader and BufferedReader and then start checking :
outer loop -->while readLine is not null
if line matches //d+ --> read value of number and put it into count
from 0 to count do what you want to do // inner loop
Instead of reading into a separate scanner, you can read to end of line, and use String.split, like this:
while (scanner.hasNextInt()) {
int count = scanner.nextInt();
for (int i = 0 ; i != count ; i++) {
if (!scanner.hasNext()) throw new IllegalStateException("expected a name");
String name = scanner.next();
List<Integer> numbers = new ArrayList<Integer>();
for (String numStr : scanner.readLine().split(" ")) {
numbers.add(Integer.parseInt(numStr));
}
... // Do something with name and numbers
}
}
This approach avoids the need to detect the difference between the last int on a line vs. the first integer on next line by calling readLine() after reading a name, i.e. in the middle of reading a line.
File file = new File("records.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
/* Read file one line at a time */
while((line = reader.readLine()) != null){
int noOfRecords = Integer.parseInt(line);
/* read the next n lines in a loop */
while(noOfRecords != 0){
line = reader.readLine();
String[] tokens = line.split(" ");
noOfRecords--;
// do what you need to do with names and numbers
}
}
Here we're reading one line at a time, so the first time we read a line it will be an int (call it as n), from there read the next n lines in some inner loop. Once it's done with this inner loop it will come outside and the next time you read a line it's definitely another int or EOF. That way you don't have to deal with integer parsing exceptions and we'll read all the lines only once :)

counting the number of lines in a text file (java)

Below is how i count the number of lines in a text file. Just wondering is there any other methods of doing this?
while(inputFile.hasNext()) {
a++;
inputFile.nextLine();
}
inputFile.close();
I'm trying to input data into an array, i don't want to read the text file twice.
any help/suggestions is appreciated.
thanks
If you are using java 7 or higher version you can directly read all the lines to a List using readAllLines method. That would be easy
readAllLines
List<String> lines = Files.readAllLines(Paths.get(fileName), Charset.defaultCharset());
Then the size of the list will return you number of lines in the file
int noOfLines = lines.size();
If you are using Java 8 you can use streams :
long count = Files.lines(Paths.get(filename)).count();
This will have good performances and is really expressive.
The downside (compared to Thusitha Thilina Dayaratn answer) is that you only have the line count.
If you also want to have the lines in a List, you can do (still using Java 8 streams) :
// First, read the lines
List<String> lines = Files.lines(Paths.get(filename)).collect(Collectors.toList());
// Then get the line count
long count = lines.size();
If you just want to add the data to an array, then I append the new values to an array. If the amount of data you are reading isn't large and you don't need to do it often that should be fine. I use something like this, as given in this answer: Reading a plain text file in Java
BufferedReader fileReader = new BufferedReader(new FileReader("path/to/file.txt"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
String everything = sb.toString();
} finally {
br.close();
}
If you are reading in numbers, the strings can be converted to numbers, say for integers intValue = Integer.parseInt(text)
I do not have enough reputation to comment but #superbob answer is almost perfect, indeed you must ensure to pass Charset.defaultCharset() as 2nd parameter like :
Files.lines(file.toPath(), Charset.defaultCharset()).count()
That's because Files.lines used UTF-8 by default and then using as it is on non default UTF-8 system can produce java.nio.charset.MalformedInputException.

Categories

Resources