I'm trying to create a class that uses a separate method to read and store two sets of data from a file into 2 different arrays. I don't know if it's the read method or my output that is incorrect but I can't seem to figure out how to have it printout all data sets. I get the last line of the file instead of all content.
examples from products.txt are
Product1,1100
Product2,1205
Product3,1000
Main Method
String[] pName;
double[] pPrice;
String outputStr = null;
int i = 0;
//String name = null;
// Input number of customers
//initialize arrays with size
pPrice=new double[50];
pName=new String[50];
// read from file, the method is incomplete
try {
readFromFile(pName, pPrice, "products.txt");
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "File cannot be read");
e.printStackTrace();
}
for (i = 0; i < pName.length; i++) {
outputStr = pName[i] + "," + pPrice[i] + "\n";
}
// Call method before sorting both arrays
display(outputStr);
Reading Method
public static void readFromFile(String[] pName, double[] pPrice, String fileName) throws FileNotFoundException {
// read data from products
// Create a File instance
File file = new File(fileName);
// Create a Scanner for the file
Scanner sc = new Scanner(file);
// Read data from a file, the data fields are separated by ','
// Change the Scanner default delimiter to ','
sc.useDelimiter(",|\r\n");
// Start reading data from file using while loop
int i = 0;
while (sc.hasNext()) {
String name = sc.next();
String cost = sc.next();
//add the customer data through arrays
pName[i] = name;
pPrice[i] = Double.parseDouble(cost);
i++;
}//end while
// Close the file
The problem is that your for loop assigns every line to the outputStr variable:
for (i = 0; i < pName.length; i++) {
outputStr = pName[i] + "," + pPrice[i] + "\n";
}
Seeing your linefeed in the end I assume you want to concatenate all lines into that string variable. So change that code into
for (i = 0; i < pName.length; i++) {
outputStr += pName[i] + "," + pPrice[i] + "\n";
}
As you initialize the variable to be null this may throw a NullPointerException. If that is the case, simply initialize with "".
Related
For my Java class, I'm working on a project that is essentially a database for MTG cards. I have to read from a file as part of the project, so I am reading the card information from a file, and then splitting the lines to put each different type of information together to form different object classes for the different types of cards. The main nitpicky issue I'm running into right now is that I need the card text to be on one line in the text file so I can read it line by line, but I'd prefer if it weren't all on one line when I print it to the console. Is there any way to add a character combination into the text of the file itself that will tell my compiler, "line break here," when it reads that, or am I out of luck? I know I could just use \n in the code to achieve this, but as I am looping through the file, there is no way to do so properly that I know of, as not every card's text needs line breaks inserted. If it matters, this is the chunk of my code that deals with that:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Scanner;
public class MTG {
public static void main(String[] args) {
int creatureLength = 4;
//Prompt User
Scanner sc = new Scanner(System.in);
System.out.println("Welcome to the Magic: the Gathering card database. This tool currently supports Rare and Mythic Rare cards from the Throne of Eldraine Expansion.");
try {
System.out.println("\nSelect the card type you'd like to view.");
System.out.println(""
+ "(1)Creatures\n"
);
int choice = Integer.parseInt(sc.next());
//Choose type
//Creatures
if(choice == 1){
Creature[] creatures = creatureGen("textfiles/Creatures.txt", creatureLength);
System.out.println("\nViewing creatures. Which card would you like to view?: \n");
for(int k = 0; k < creatureLength; k++) {
System.out.println(
"(" + (k + 1) + ") " + creatures[k].getName());
}
int creatureChoice = Integer.parseInt(sc.next());
try {
System.out.println("\n" + creatures[(creatureChoice - 1)]);}
catch(Exception e) {
System.out.println("Input was not a specified number. Exiting...");
}
}
}
catch(NumberFormatException ex){
System.out.println("Input was not a specified number. Exiting...");
}
sc.close();
}
//Read Creature text file
public static Creature[] creatureGen(String path, int length) {
Creature[] creatures = new Creature[length];
try {
FileReader file = new FileReader(path);
BufferedReader reader = new BufferedReader(file);
String name[] = new String[length];
String cost[] = new String[length];
String color[] = new String[length];
String type[] = new String[length];
String cTypes[] = new String[length];
String tags[] = new String[length];
String text[] = new String[length];
int power[] = new int[length];
int toughness[] = new int[length];
for (int i = 0; i < length; i++) {
String line = reader.readLine();
if(line != null) {
name[i] = line.split("\\|")[0];
cost[i] = line.split("\\|")[1];
color[i] = line.split("\\|")[2];
type[i] = line.split("\\|")[3];
cTypes[i] = line.split("\\|")[4];
tags[i] = line.split("\\|")[5];
text[i] = line.split("\\|")[6];
power[i] = Integer.parseInt(line.split("\\|")[7]);
toughness[i] = Integer.parseInt(line.split("\\|")[8]);
creatures[i] = new Creature(name[i], cost[i], color[i], type[i], cTypes[i], tags[i], text[i], power[i], toughness[i]);
}
}
reader.close();
}
catch (Exception e) {
System.out.println("Error reading file: " + path);
}
return creatures;
}
}
The Creature object class essentially just stores the data that I am putting into it with the creatureGen method. A sample line from the text file I am reading from looks something like this:
Charming Prince|1W|White|Creature|Human Noble||When Charming Prince enters the battlefield, choose one — • Scry 2. • You gain 3 life. • Exile another target creature you own. Return it to the battlefield under your control at the beginning of the next end step.|2|2
It would be ideal to be able to insert line breaks after each of the bullet points in this card, for example, but as I said earlier, I need the text to be in one line for my loop to read it. Is there any way around this when I print this back to the console? I appreciate any help.
Just replace those bullet points with line breaks :
text[i] = line.split("\\|")[6].replaceAll("•","\n");
Also, you should not split each time you need an element, put the result of line.split("\|") in a String[] variable and use it afterwards.
for (int i = 0; i < length; i++) {
String line = reader.readLine();
if(line != null) {
String[] elements = line.split("\\|");
name[i] = elements[0];
cost[i] = elements[1];
color[i] = elements[2];
type[i] = elements3];
cTypes[i] = elements[4];
tags[i] = elements[5];
text[i] = elements[6].replaceAll("•","\n");
power[i] = Integer.parseInt(elements[7]);
toughness[i] = Integer.parseInt(elements[8]);
creatures[i] = new Creature(name[i], cost[i], color[i], type[i], cTypes[i], tags[i], text[i], power[i], toughness[i]);
}
}
Finally, about vocabulary, the compiler is not reading your file. The compiler translates your code into binary instructions for the processor (to summarize).
Your file is read at runtime.
I am creating a program that is reading a file of names and ages then printing them out in ascending order. I am parsing through the file to figure out the number of name age pairs and then making my array that big.
The input file looks like this:
(23, Matt)(2000, jack)(50, Sal)(47, Mark)(23, Will)(83200, Andrew)(23, Lee)(47, Andy)(47, Sam)(150, Dayton)
When I am running my code I get the output of (0,null) and I am not sure why. I have been trying to fix it for a while and am lost. If anyone can help that would be great My code is below.
public class ponySort {
public static void main(String[] args) throws FileNotFoundException {
int count = 0;
int fileSize = 0;
int[] ages;
String [] names;
String filename = "";
Scanner inputFile = new Scanner(System.in);
File file;
do {
System.out.println("File to read from:");
filename = inputFile.nextLine();
file = new File(filename);
//inputFile = new Scanner(file);
}
while (!file.exists());
inputFile = new Scanner(file);
if (!inputFile.hasNextLine()) {
System.out.println("No one is going to the Friendship is magic Party in Equestria.");
}
while (inputFile.hasNextLine()) {
String data1 = inputFile.nextLine();
String[] parts1 = data1.split("(?<=\\))(?=\\()");
for (String part : parts1) {
String input1 = part.replaceAll("[()]", "");
Integer.parseInt(input1.split(", ")[0]);
fileSize++;
}
}
ages = new int[fileSize];
names = new String[fileSize];
while (inputFile.hasNextLine()) {
String data = inputFile.nextLine();
String[] parts = data.split("(?<=\\))(?=\\()");
for (String part : parts) {
String input = part.replaceAll("[()]", "");
ages[count] = Integer.parseInt(input.split(", ")[0]);
names[count] = input.split(", ")[1];
count++;
}
}
ponySort max = new ponySort();
max.bubbleSort(ages, names, count);
max.printArray(ages, names, count);
}
public void printArray(int ages[], String names[], int count) {
System.out.print("(" + ages[0] + "," + names[0] + ")");
// Checking for duplicates in ages. if it is the same ages as one that already was put in them it wont print.
for (int i = 1; i < count; i++) {
if (ages[i] != ages[i - 1]) {
System.out.print("(" + ages[i] + "," + names[i] + ")");
}
}
}
public void bubbleSort(int ages[], String names[], int count ){
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - i - 1; j++) {
// age is greater so swaps age
if (ages[j] > ages[j + 1]) {
// swap the ages
int temp = ages[j];
ages[j] = ages[j + 1];
ages[j + 1] = temp;
// must also swap the names
String tempName = names[j];
names[j] = names[j + 1];
names[j + 1] = tempName;
}
}
}
}
}
output example
File to read from:
file.txt
(0,null)
Process finished with exit code 0
What your code does is to Scan the file twice.
In the first loop you do
String data1 = inputFile.nextLine();
Code reads first line and then scanner goes to the next (second) line.
Later you do again inputFile.nextLine(); The second line is empty and the code never goes into the second loop and content is never read.
If you can use Lists, you should create two array lists and add ages and names into the arraylists in the first scan, so you scan the file once. When done, you could get the Array out of the arraylist.
If you should only use arrays and you want a simple update, just add another Scanner before the second loop:
ages = new int[fileSize];
names = new String[fileSize];
inputFile = new Scanner(file); // add this line
I've got the following code that opens and read a file and separates it to words.
My problem is at making an array of these words in alphabetical order.
import java.io.*;
class MyMain {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Kennedy.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
int line_count=0;
int byte_count;
int total_byte_count=0;
int fromIndex;
while( (line = br.readLine())!= null ){
line_count++;
fromIndex=0;
String [] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
String line_rest=line;
for (int i=1; i <= tokens.length; i++) {
byte_count = line_rest.indexOf(tokens[i-1]);
//if ( tokens[i-1].length() != 0)
//System.out.println("\n(line:" + line_count + ", word:" + i + ", start_byte:" + (total_byte_count + fromIndex) + "' word_length:" + tokens[i-1].length() + ") = " + tokens[i-1]);
fromIndex = fromIndex + byte_count + 1 + tokens[i-1].length();
if (fromIndex < line.length())
line_rest = line.substring(fromIndex);
}
total_byte_count += fromIndex;
}
}
}
I would read the File with a Scanner1 (and I would prefer the File(String,String) constructor to provide the parent folder). And, you should remember to close your resources explicitly in a finally block or you might use a try-with-resources statement. Finally, for sorting you can store your words in a TreeSet in which the elements are ordered using their natural ordering2. Something like,
File file = new File("C:/", "Kennedy.txt");
try (Scanner scanner = new Scanner(file)) {
Set<String> words = new TreeSet<>();
int line_count = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
line_count++;
String[] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
Stream.of(tokens).forEach(word -> words.add(word));
}
System.out.printf("The file contains %d lines, and in alphabetical order [%s]%n",
line_count, words);
} catch (Exception e) {
e.printStackTrace();
}
1Mainly because it requires less code.
2or by a Comparator provided at set creation time
If you are storing the tokens in a String Array, use Arrays.sort() and get a naturally sorted Array. In this case as its String, you will get a sorted array of tokens.
I am having this issue with the NumberFormatException in my program. Basically, I am asked to read a .csv file separated by ; and it looks like this:
// Column Explanation (not in .csv file)
id; Summary; Number; Employee1; Employee2; ....... Employee7;
"1";"Sony";"1600";"Markos";"Nikos";"Antonis";"Nikolas";"Vaggelis";"Markos";"Thanasis";
"2";"HP";"1000";"Marios";"Dimitra";"Nikolia";"Spiros";"Thomas";"Kostas";"Manolis";
"3";"Dell";"1100";"Antonis";"Aggelos";"Baggelis";"Nikos";"Kuriakos";"Panagiotis";"Rafail";
"4";"Acer";"2000";"Marina";"Aggelos";"Spiros";"Marinos";"Xristos";"Antreas";"Basilis";
What I have already done is create a String 2-d array or the .csv file called temp_arr and I am asked to write a method that will run a linear search by id and return that company. So here is the thing.
At first, I thought I should convert the input key from int -> String since my temp_arr is a String and compares the strings (which at that time they would be int but read as Strings) using temp_arr[value][value2].equals(string_key). But I had a NullPointerException.
Then I thought I should better convert my Id's from the temp_arr from String -> Int and then compare with the integer key using == operand. This action returned me a NumberFormatException.
The process is this:
System.out.println("Enter id :");
Scanner input = new Scanner(System.in);
int item = input.nextInt(); // read the key which is an Integer
int id_int; // temp_arr is String and item is int, must convert ids from String -> int
for (int i = 0; i < temp_arr.length; i++)
{
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int
if (id_int == item) // If the Array's Id's are == item
{
System.out.println(item+" is present at location " + (i+1) );
break;
}
if (i == temp_arr.length)
System.out.println(item + " does not exist");
}
My error appears at line 7 and I do not know why.
Read File process:
String csvFile = "sam.csv"; // .csv file to be placed in the project file!
BufferedReader br = null; // ini
String line = "",cvsSplitBy = ";"; // columns asked to be split by ";"
String[] arr = null;
String[][] temp_arr = new String[1000][10];
int temp = 0;
try
{
br = new BufferedReader(new FileReader(csvFile)); //start reading the file
while ((line = br.readLine()) != null) // while the line has words
{
arr = line.split(cvsSplitBy); // creating the array
System.out.println(arr[0] + "\t" + arr[1] + "\t" + arr[2] + "\t" + arr[3] + "\t" + arr[4] + "\t" + arr[5] + "\t" + arr[6] + "\t" + arr[7] + "\t" + arr[8] + "\t" + arr[9] );
for (int i = 0; i<=9; i++)
{
temp_arr[temp][i] = arr[i]; // temp_arr represents (is a copy of) the .csv file
}
temp++;
}
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
if (br != null)
{
try
{
br.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
System.out.println("Done!\n");
Output (Image) :
Line 106 which is causing the issue is :
id_int = Integer.parseInt(temp_arr[i][0]); // Convert from String to int
Your issue is that your Integer.parseInt() is trying to parse a "2" WITH QUOTATION MARKS. That's the problem.
A quick solution would be to replace this line:
temp_arr[temp][i] = arr[i];
To this:
temp_arr[temp][i] = arr[i].replaceAll("\"", "");
Anyway, I'd like to suggest using a different data structure for your case, because I've done something like this before for a client. Have you ever heard of HashMaps? You can do something like a HashMap with an int key and String[] values to store your data in, and the key can be your id_int. Maybe you can try this implementation next time. It's a lot more elegant.
Hope I was able to help!
Cheers,
Justin
Would help if you also posted some of your data file and how you are reading it in.
But, my guess from what is presented is if you add System.out.println(temp_arr[i][0]) prior to the 7th line or run this code through a debugger you will see that temp_arr[i][0] is not an integer value as that is what the error is telling you.
I want to take a text file which contains strings and integers and individually take certain integers on each line and assign that specific integer to a variable to be later accessed by other classes. Here is what i have so far, I'm almost certain it will not work:
public void openInputFile()
{
String fileName = "concerts.txt";
Scanner inputStream = null;
try{
inputStream = new Scanner(new File(fileName));
}
catch (FileNotFoundException e)
{
System.out.println("error");
System.exit(0);
}
while (inputStream.hasNextLine()){
int capacityM =0 ;
int ticketPriceM = 0;
int capacityO = 0;
int ticketPriceO = 0;
int capacityP = 0;
int ticketPriceP = 0;
if (inputStream.equals("Maroon 5")){
capacityM = inputStream.nextInt(); //I want to read line #2 of the txt file assign it here
ticketPriceM = inputStream.nextInt();//Line 3 of txt file needs to be assigned here
}
else if(inputStream.equals("One Direction")){
capacityO = inputStream.nextInt(); //
ticketPriceO = inputStream.nextInt();
}
else {
capacityP = inputStream.nextInt();
ticketPriceP = inputStream.nextInt();
}
System.out.println(capacityM + ticketPriceM + capacityO +
ticketPriceO + capacityP + ticketPriceP);
}
inputStream.close();
}
}
Here is What the text file looks like that is being read from. I'm not sure if i should use arrays.
Maroon 5
15 //number of tickets available
40 //ticket price
One Direction
10
50
Pearl Jam
20
30
You should use nextLine method to read the line from file. Than use equals method to compare String at else-if
String line=inputStream.nextLine();//Call nextLine only once
//than use the line to compare
//different condition
if (line.equals("Maroon 5")){
....
}else if(line.equals("One Direction")){
.....
}