Reading a file and storing names and numbers in two arrays - java

I'm working on a program that reads a file and stores the names and scores in two separate arrays, but I'm struggling. This is what I have so far.
I created an array for names called names, but I'm confused how I would copy the names into each index of the array.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ScannerReadFileSplit {
public static void main(String[] args) {
File file = new File("NamesScore.txt");
String[] names = new String[100];
int[] scores = new int[100];
int i;
try {
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String [] words = line.split("\t");
for (String word: words) {
System.out.println(word);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
My text file is:
John James 60
Kim Parker 80
Peter Dull 70
Bruce Time 20
Steve Dam 90

First, you will want to initialize i to 0 when you declare it:
int i = 0;
Then, after splitting the line you can pull the data out of the String[] and put it in your names and scores arrays:
String [] words = line.split("\t");
// The first element in 'words' is the name
names[i] = words[0];
// The second element in 'words' is a score, but it is a String so we have
// to convert it to an integer before storing it
scores[i] = Integer.parseInt(words[1], 10);
// Increment 'i' before moving on to the next line in our file
i++;
Don't forget to increment i as shown above.
There is some error checking that I have glossed over. You will probably want to check that words has a length of 2 after your call to split(). Also keep in mind that Integer.parseInt() can throw a NumberFormatException if it is not able to parse the data in the scores column as an integer.

I have tried to correct your code and provided inline comments where I felt you have went wrong. Actually you were close to the solution. Try to figure out what you are getting as an output after a line of code like
String[] words = line.split("\t");
This line will give two String(as it will split the line in your file which has only one tab separated name and score). And you can try to debug by yourself. Like simply printing the value. for example
System.out.println(words[0]);
This will help you progress further.
Hope this helps.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TwoArrays {
public static void main(String[] args) {
File file = new File("C:\\test\\textTest.txt");
String[] names = new String[100];
int[] scores = new int[100];
int i = 0;
try {
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] words = line.split("\t");
names[i] = words[0]; // storing value in the first array
scores[i] = Integer.parseInt(words[1]); // storing value in the
// second array
i++;
}
/*
* This piece of code will give unnecessary values as you have
* selected an array of size greater than the values in the file for
*
* for(String name: names) {
* System.out.println("Name:- "+name);
* }
* for(int score: scores) {
* System.out.println("Score:- "+score);
* }
*/
// Better use the below way, here i am restricting the iteration till i
// i is actually the count of lines your file have.
for (int j = 0; j < i; j++) {
System.out.println("Name:- " + names[j] + "\t" + "Score:- " + scores[j]);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}

what about
int l = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String [] words = line.split("\t");
names[l] = words[0];
scores[l] = Integer.parseInt(words[1]);
System.out.println(l + " - name: " + names[l] + ", score: " + scores[l]);
l++;
}

Related

Best way to read CSV file and store (array, 2darray?) and print to screen in tabular format?

The thing i'm hoping to do is read a csv file with 6 rows and 6 columns in it using Java. I then need to print out each row and allow the user to select 1 option. Here is what I have, I know my code chooses 1 and prints it, but I don't know how to change it from printing one random row, to printing all 6 rows. Probably in an ArrayList or 2dArray?
package theContest;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Random;
import java.util.Scanner;
public class theContest {
// The main() method
public static void main(String[] args) throws FileNotFoundException {
//
String fileName = "contest.csv";
File file = new File(fileName);
if (!file.isFile()) {
System.err.println("Cannot open file: " + fileName + ".");
System.exit(0);
}
//
int numContest = 0;
Scanner input = new Scanner(file);
while (input.hasNext()) {
input.nextLine();
numContest++;
}
input.close();
System.out.println("Total of " + numContest + " contestants.");
//
int winner = 0;
Random random = new Random();
winner = random.nextInt(numContest) + 1;
System.out.println("The winner is contestant number " + winner + ".");
//
String winnerDetails = "";
input = new Scanner(file);
for (int lineCount = 0; lineCount < winner; lineCount++) {
winnerDetails = input.nextLine();
}
input.close();
System.out.println("Winner is: " + winnerDetails);
//
String id = "";
String name = "";
String seats = "";
String trans = "";
String rate = "";
String price = "";
input = new Scanner(winnerDetails);
input.useDelimiter(",");
id = input.next();
name = input.next();
seats = input.next();
trans = input.next();
rate = input.next();
price = input.next();
input.close();
System.out.println("Details are:");
System.out.printf("%-5s : %s\n", "ID", id);
System.out.printf("%-5s : %s\n", "Name", name);
System.out.printf("%-5s : %s\n", "Seating", seats};
System.out.printf("%-5s : %s\n", "Transfer", trans};
System.out.printf("%-5s : %s\n", "Rate", rate};
System.out.printf("%-5s : %s\n", "Price", price};
}
}
Here:
for (int lineCount = 0; lineCount < winner; lineCount++) {
winnerDetails = input.nextLine();
}
Your file has N rows. The above code iterates all lines, and stores the result in a single variable. In each iteration, you overwrite what you put there before. So, what your code does is: it reads N lines, and throws away everything prior the last row.
In other words: if you have 6 lines, and you want to print all of them ... then that all your processing needs to be "part" of a loop, too.
For example, you could turn winnerDetails into an array of String, and then put each line in its own slot. Then you loop over the array, and print each slot.
And as you already know about ArrayList, best use that then. That also means: you need to read the file only once. Open the file, read each line, and push that into an ArrayList. Afterwards, you can do whatever you want with that list.
And note: that is actually the point you should start with. Dont solve your whole problem at once. Slice it into smaller parts. Like: reading data from CSV ... has nothing to do with later processing the lines and printing those. You can write code that just takes an ArrayList, processes those and prints stuff. Which you can ... test on its own, as you can hardcode such lists in your code.

Program that reads file input and displays proportion of the length of the letter and so on

I have an assignment due two days and I have been trying a lot of days to do this, but I am burned, tried to come back to it, still no progress.
THE ASSIGNMENT is the following:
Java program that computes the above statistics from
any text file. Here’s what it might look like in action:
Name of the input file: example.txt
The proportion of 1-letter words: 3.91% (74 words)
The proportion of 2-letter words: 18.52% (349 words)
The proportion of 3-letter words: 24.24% (456 words)
The proportion of 4-letter words: 19.80% (374 words)
The proportion of 5-letter words: 11.33% (212 words)
…
…
The proportion of 12-letter words: 0.45% (8 words)
Proportion of 13- (or more) letter words: 0.51% (9 words)
Now In order to do this, I thought to divide my program into three methods: Read the method, count the letters and distinguish them and finally display it as the example above. Now that I said that, here is my code right now:
/*like make smaller functions
where each function has one task
like to loop through the file and return an array of words
then use that as input to another function whose purpose is to count the
letters
and then pass that array into a function for printing that.
*/
import java.io.*;
import java.util.Scanner;
class Autorship {
public static void main(String[] args) {
try {
System.out.println("Name of input file: ");
Scanner sc1 = new Scanner(System. in );
sc1.useDelimiter("[^a-zA-Z]");
String fname = sc1.nextLine();
sc1.close();
sc1 = new Scanner(new FileReader(fname));
sc1.useDelimiter("[^a-zA-Z]");
String line;
System.out.println(WordCount(fname, sc1));
} catch (FileNotFoundException e) {
System.out.println("There was an error opening one of the files.");
}
}
public static int WordCount(String fname, Scanner sc1) {
int wordCount = 0;
int lineCount = 0;
while (sc1.hasNextLine()) {
String line;
line = sc1.nextLine();
lineCount++;
String[] strings = line.split(" ");
int[] counts = new int[14];
for (String str: strings)
if (str.length() < counts.length) counts[str.length()] += 1;
System.out.println("This is counts length: " + counts.length);
for (int i = 1; i < counts.length; i++)
System.out.println(i + " letter words: " + counts[i]);
}
return 0;
}
}
Now please I do not want the answer, as that would be plagiarism, and I am not that kind of person, I just want a bit of help to continue to progress, I'm so stuck right now, thanks ^^
Here is an adjusted and working version. I commented the lines I edited.
Your code wasn't that bad and it was working quite well. The only problem you had was that you've printed out the letter counts inside the while-loop instead of doing it outside. Therefore it repeated with every new line that was read from the file.
Please note: I strongly recommend to always use curly brackets even though Java syntax allows to not use them with if-statements and for-loops if they're followed by only one line of code to execute. But not using them makes the code harder to read and error prone.
public static void main(String[] args) {
try {
System.out.println("Name of input file: ");
Scanner sc1 = new Scanner(System. in );
sc1.useDelimiter("[^a-zA-Z]");
String fname = sc1.nextLine();
sc1.close();
sc1 = new Scanner(new FileReader(fname));
sc1.useDelimiter("[^a-zA-Z]");
String line;
System.out.println("WordCount: " + WordCount(fname, sc1)); // edited
} catch (FileNotFoundException e) {
System.out.println("There was an error opening one of the files.");
}
}
public static int WordCount(String fname, Scanner sc1) {
int wordCount = 0;
int lineCount = 0;
final int MAXIMUM_LENGTH = 14; // edited. Better use a constant here.
int[] counts = new int[MAXIMUM_LENGTH]; // edited. Constant applied
while (sc1.hasNextLine()) {
String line = sc1.nextLine();
// increment line count
lineCount++;
String[] strings = line.split(" ");
// increment word count
wordCount += strings.length; // added
// edited. curly brackets and constant MAXIMUM_LENGTH
for (String str: strings) {
if (str.length() < MAXIMUM_LENGTH) {
counts[str.length()] += 1;
}
}
}
// edited / added. finally show the results
System.out.println("maximum length: " + MAXIMUM_LENGTH);
System.out.println("line count: " + lineCount);
System.out.println("word count: " + wordCount);
// edited. moved out of the while-loop. MAXIMUM_LENGTH applied.
for (int i = 1; i < MAXIMUM_LENGTH; i++) {
System.out.println(i + " letter words: " + counts[i]);
}
// edited.
return wordCount;
}

FileStatistics -- trouble counting the number of words in a file

In my course, we are tasked with determining three key statistics about a file that is passed via the console input: 1) number of characters, 2) number of lines, 3) number of words. Before closing this question as a duplicate, please read on to see what unique problem I'm encountering. Thank you :)
I originally wrote a solution with three separate methods and three separate Scanner variables, but I realized that for larger files, this solution would be very inefficient. Instead, I decided to write up a solution that only runs through the file a single time and calculates all three statistics in one go. Here is what I have so far:
import java.util.*;
import java.io.*;
public class FileStatistics
{
// Note: uncomment (A) and (B) below to test execution time
public static void main( String [] args ) throws IOException
{
/* (A)
long startTime = System.currentTimeMillis();
*/
File file = new File(args[0]);
Scanner input = new Scanner(file);
int numChars = 0, numWords = 0, numLines = 0;
/* Calculations */
while( input.hasNextLine() )
{
String currentLine = input.nextLine();
numLines++;
numChars+= currentLine.length();
String [] words = currentLine.split(" ");
numWords += words.length;
}
input.close();
/* Results */
System.out.println( "File " + file.getName() + " has ");
System.out.println( numChars + " characters");
System.out.println( numWords + " words");
System.out.println( numLines + " lines");
/* (B)
long endTime = System.currentTimeMillis();
System.out.println("Execution took: " + (endTime-startTime)/1000.0 + " seconds");
*/
}
}
I've been comparing the results of my program to Microsoft Word's own file statistics by simply copy/pasting the contents of whatever file I'm using into Word. The number of characters and number of lines are calculated correctly.
However, my program does not properly count the number of words. I decided to include a test statement in there to print out the contents of the array words, and it seems that certain "spatial formatting" (like tabs from a Java source code file) are being treated as individual elements in the split array. I tried doing currentLine.replace("\t", "") before invoking the split method to remove those tabs, but this didn't change a thing.
Could someone please offer some advice or hints as to what I'm doing wrong?
This is because the String array returned by currentLine.split(" ") can contain elements which are empty Strings: "". You can see this if you call System.out.println(Arrays.toString(words)).
To create the desired behavior, you can store words.length in a variable count and decrement count for each instance of the empty string "" in words.
Here is a sample solution:
while( input.hasNextLine() )
{
String currentLine = input.nextLine();
numLines++;
numChars+= currentLine.length();
String [] words = currentLine.split("\\s+");
int count = words.length;
for (int i = 0; i < words.length; i++) {
if (words[i].equals("")) {
count--;
}
}
numWords += count;
}
Alternatively, you can convert words to an ArrayList and use the removeAll() functions:
while( input.hasNextLine() )
{
String currentLine = input.nextLine();
numLines++;
numChars+= currentLine.length();
ArrayList<String> words = new ArrayList<>(Arrays.asList(currentLine.split("\\s+")));
words.removeAll(Collections.singleton(""));
numWords += words.size();
}

For loop iterating through string and adding/replacing characters

I need to write for loop to iterate through a String object (nested within a String[] array) to operate on each character within this string with the following criteria.
first, add a hyphen to the string
if the character is not a vowel, add this character to the end of the string, and then remove it from the beginning of the string.
if the character is a vowel, then add "v" to the end of the string.
Every time I have attempted this with various loops and various strategies/implementations, I have somehow ended up with the StringIndexOutOfBoundsException error.
Any ideas?
Update: Here is all of the code. I did not need help with the rest of the program, simply this part. However, I understand that you have to see the system at work.
import java.util.Scanner;
import java.io.IOException;
import java.io.File;
public class plT
{
public static void main(String[] args) throws IOException
{
String file = "";
String line = "";
String[] tempString;
String transWord = ""; // final String for output
int wordTranslatedCount = 0;
int sentenceTranslatedCount = 0;
Scanner stdin = new Scanner(System.in);
System.out.println("Welcome to the Pig-Latin translator!");
System.out.println("Please enter the file name with the sentences you wish to translate");
file = stdin.nextLine();
Scanner fileScanner = new Scanner(new File(file));
fileScanner.nextLine();
while (fileScanner.hasNextLine())
{
line = fileScanner.nextLine();
tempString = line.split(" ");
for (String words : tempString)
{
if(isVowel(words.charAt(0)) || Character.isDigit(words.charAt(0)))
{
transWord += words + "-way ";
transWord.trim();
wordTranslatedCount++;
}
else
{
transWord += "-";
// for(int i = 0; i < words.length(); i++)
transWord += words.substring(1, words.length()) + "-" + words.charAt(0) + "ay ";
transWord.trim();
wordTranslatedCount++;
}
}
System.out.println("\'" + line + "\' in Pig-Latin is");
System.out.println("\t" + transWord);
transWord = "";
System.out.println();
sentenceTranslatedCount++;
}
System.out.println("Total number of sentences translated: " + sentenceTranslatedCount);
System.out.println("Total number of words translated: " + wordTranslatedCount);
fileScanner.close();
stdin.close();
}
public static boolean isVowel (char c)
{
return "AEIOUYaeiouy".indexOf(c) != -1;
}
}
Also, here is the example file from which text is being pulled (we are skipping the first line):
2
How are you today
This example has numbers 1234
Assuming that the issue is StringIndexOutOfBoundsException, then the only way this is going to occur, is when one of the words is an empty String. Knowing this also provides the solution: do something different (if \ else) when words is of length zero to handle the special case differently. This is one way to do this:
if (!"".equals(words)) {
// your logic goes here
}
another way, is to simply do this inside the loop (when you have a loop):
if ("".equals(words)) continue;
// Then rest of your logic goes here
If that is not the case or the issue, then the clue is in the parts of the code you are not showing us (you didn't give us the relevant code after all in that case). Better provide a complete subset of the code that can be used to replicate the problem (testcase), and the complete exception (so we don't even have to try it out ourselves.

String operation in Java

Is this code correct? I have mentioned my doubts in the form of comments in some places:
public class pract1
{
public static void main (String[] args)
{
int i;
String [] array = new String[20]; // Is this declaration correct?
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the Array: ");
array = br.readLine(); // Is this the correct way to accept input from keyboard?
i=0;
while(array[i]!='\0') // Can I use the null pointer concept in Java?
{
System.out.println("The "+(i+1)+"character is:" +array[i]+"\n"); //Want to print each and every characters in string along with its position
i++;
}
}
}
This is how you could also do it:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Pract1
{
public static void main (String[] args)
{
String array = ""; //initialize an empty string that will hold the value from the keyboard
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // initialize the BufferedReader
// while "stop" is not typed on the console, keep running
while(!array.equals("stop")) {
System.out.println("Enter the Array: ");
try {
array = br.readLine(); // read from the console
System.out.println("Array:" + array);
for(int i=0; i<array.length(); i++) { //loop through the input and show the chars
System.out.println("Character "+(i+1)+" is: " +array.charAt(i));
}
} catch (Exception e) { // catch any exception and show only the message, not the entire stackTrace
System.out.println("Error: " + e.getMessage());
}
System.out.println("");
}
}
}
Java string is an object, not array. If you are more comfortable with array, use split() to get an array of String. You should note that each element in the derived array is String Object with only one letter, not primitive Char.
String[] array = "abc".split("");
for(int i; i< array.length; i++)
{
System.out.println("The "+(i+1)+"character is:" +array[i]+"\n");
}
You may want to read this Question to get the idea of String Object in Java Difference between "char" and "String" in Java
Array declaration
String [] array = new String[20]; // Is this declaration correct?
This declaration is correct for an array of 20 slots of type String (all of them initialized to null). But you might not need this right away, or not in this form.
You don't need to initialize the variable, especially if you overwrite that initialization by an instruction like: array = ....
Getting Input
array = br.readLine(); // Is this the correct way to accept input from keyboard?
Yes, readLine() is the way to go, but as the doc states, and as you will be told by the compiler, readLine(); does not return an array of Strings but a single String. You should use a String variable instead:
// initialize a String variable 'line' containing the whole line without the '\n' at the end
String line = br.readLine();
UPDATE: You could also use the Scanner class instead, that's usually what we do. Then, use sc.nextLine() for similar results as br.readLine(), as stated there.
Printing the chars
System.out.println("The "+(i+1)+"character is:" +array[i]+"\n");
//Want to print each and every characters in string along with its position
You can access the character at a given position in a String via the method charAt(int). Also, you don't have to deal with complicated C stuff such as looking for the end of the string via '\0'. You should instead use a proper for loop, like this:
String line = br.readLine();
for (int i = 0; i < line.length(); i++) {
System.out.println("The "+(i+1)+" character is: " + line.charAt(i) +"\n");
}
An alternate solution would be to use the toCharArray() method:
String line = br.readLine();
char[] chars = line.toCharArray();
for (int i = 0; i < chars.length; i++) {
System.out.println("The "+(i+1)+" character is: " + chars[i] +"\n");
}

Categories

Resources