I have a text file like this;
7-Georgia
1-Andrew
6-John
8-Luke
9-Erica
3-Kim
2-Jude
5-Phil
4-Leo
The first column is id and second is name. How can I get these id's and names? So far I wrote this;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
public class Main {
#SuppressWarnings("resource")
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
#SuppressWarnings("unused")
Scanner fromFile = new Scanner(new File("id_name.txt"));
fromFile.useDelimiter("-");
while(fromFile.hasNext()){
String temp = fromFile.next();
System.out.println(temp);
}
while(fromFile.hasNext()){
String temp= fromFile.next();
int[] fileID;
fileID= new int[9];
for(int i=0; i<9; i++){
fileID[i]= Integer.parseInt(temp);
}
System.out.println(fileID);
}
}
}
But this doesn't get the id's. I'm not sure how to fix this, I'd be grateful if you help me.
You have two while loops in your code. Typically one while loop will go through every item until the condition is no longer true. I think you need to rework this to have a better "flow of control" which might mean using only one while loop (with sections to grab the number and then the name.
I imagine that you are looking for results from the second while loop, but by the time you get to it, the first while loop will have exhausted all of your data.
Finally, printing an array will print out the array reference identifier. If you want to actually print the contents of the array, you need a loop over the elements within the array, and you need to print out each array element explicitly.
As an alternative to the array printing technique above (which you should master), you can also use the Arrays.toString(<insert array here>) method call. However, in many cases it will give you a format that is not desired. That's why you need to know the above technique too.
Also, you have one hidden issue. You (in the second while loop) make the assumption that there are only nine inputs. Pay close attention to what you are writing. Every time you have to reach for a number, consider whether it is a "magic" number. Magic numbers are numbers that are in your code with no explanation or reason why they exist. They are indicators of errors in the code made by assumptions that probably won't last the test of time.
For example, you are using the number 9 because you have seen the input file. The next input file will probably not have nine entries in it, and your program will probably not work right if you gave it an input with eight entries, or an input with ten entries. Perhaps you should rewrite the loop to remove the magic number, by making the logic process while there is still (some) input.
Try this on for size
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
Scanner fromFile = new Scanner(new File("id_name.txt"));
} catch (FileNotFoundException e) {
System.err.println("File not found");
}
String[] arr = new String[9];
String[] oth = new String[9];
int i = 0;
while(fromFile.hasNextLine()) {
String temp = fromFile.nextLine();
oth[i] = temp.substring(0,1);
arr[i] = temp.substring(2);
i++;
}
int[] fileID;
fileID = new int[9];
for(int j = 0; j < 9; j++) {
fileID[j] = Integer.parseInt(oth[j]);
}
}
}
this should go through and retrieve the numbers(.substring(0,1)) and then the names(.substring(2)), and then converting the numbers to int values.
Try the following:
File file=new File("id_name.txt");
int[] fileID;
fileID= new int[9];
String[] result = file.nextLine().split("-");
for (int x = 0; x < result.length; x++){
if (Character.isDigit(result[x])) { // use the isDigit method to get the ids
System.out.println("this is an id");
fileID[i]= Integer.parseInt(result[x]);
}
Actually my friend, there are several mistakes here.
1) When the first while loop completes, it leaves fromfile.hasNext() as false Hence the second loop never starts.
>> To fix this, You need to put it all in one while loop.
2) fileID is an array. You cannot print it using System.out.println(fileID).
>> You have to tell what kind of output you want. The code will depend on that. For simply printing all the values, you need to make a for loop that prints each value separartely. You should use fileID.length for the no. of times you need to loop it.
3) Basically, fromfile.next() is not the way to do it.
>> You need to use fromfile.nextLine().
Related
I was trying to scan a file that has an array of doubles. I'm using the code below but it's only outputting 0.0 for every entry. Why is this and how can I fix it?
Scanner scanner = new Scanner("file.txt");
double[] array = new double[256 * 256];
for (int i = 0; i < array.length; i++) {
if (scanner.hasNextDouble()) {
array[i] = scanner.nextDouble();
}
}
System.out.println(array[0]);
An example of the file I'm scanning is
0.22131145 0.22131145 0.22131145 0.22841525 0.22841525 ...
The main issue is with the instantiation of the Scanner object. In this case you need to pass a File object into it, not just a string, and make sure you specify the correct file path. Refer to the official documentation for advice.
Secondly, you need to use a while-loop. An if-statement will execute only once, but you would want the Scanner to continue looking whilst there is info inside the file.
Thirdly, don't use an array for storing the values. It's too risky because you need to know the size of the array beforehand, meaning that you would need to loop twice, which would be inefficient, or you are hard coding, as you are doing here. If someone were to add or remove values from the file, you will get unexpected results. Rather use a dynamic data structure such as a List.
public static void main(String[] args) throws FileNotFoundException {
String filepath = "file.txt";
Scanner scanner = new Scanner(new File(filepath));
List<Double> list = new ArrayList<>();
while (scanner.hasNextDouble()) {
list.add(Double.valueOf(scanner.next()));
}
scanner.close();
System.out.println(list.get(0));
}
There are four problems with your code:
Blocker: Scanner expects a File object but you haven't used it in this way. You need to use the following syntax:
Scanner scanner = new Scanner(new File("file.txt"));
Performance: You can improve the performance of your program by including scanner.hasNextDouble() in the condition which checks the value of i, as shown below:
for (int i = 0; i < array.length && scanner.hasNextDouble(); i++) {
array[i] = scanner.nextDouble();
}
This will terminate the loop as soon as scanner.hasNextDouble() returns false; otherwise, the loop in your code will continue to run until i < array.length evaluates to false irrespective of the value returned by scanner.hasNextDouble().
Resource leak: You have not closed the Scanner object. Put the following line after the loop finishes:
scanner.close();
Missed functionality: You haven't printed the complete array. Your statement, System.out.println(array[0]) will print only the first element in the array. Change it as follows to print the complete array:
System.out.println(Arrays.toString(array));
Given below the code incorporating all the above-mentioned comments:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File("file.txt"));
double[] array = new double[256 * 256];
for (int i = 0; i < array.length && scanner.hasNextDouble(); i++) {
array[i] = scanner.nextDouble();
}
scanner.close();
System.out.println(Arrays.toString(array));
}
}
Memory utilization: You have used a fixed-sized array which is fine if the number of elements to be stored is equal to the size of the array. However, if it is not the case (i.e. if the number of elements to be stored can be less than or more than the specified size), you should use a Collection e.g. an ArrayList which is a kind of dynamic array. This will help you in many ways: (a) You will save memory if the number of elements to be stored is less than the specified size (b) You do not need to change your code in order to increase the size of the array when you need to store more elements than you have already specified (c) The Collection provides with a rich API to deal with elements. By leveraging this API, your code can be crisp, more performant, maitainable etc.
Given below the code incorporating the 5th point:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File("file.txt"));
List<Double> list = new ArrayList<>();
while (scanner.hasNextDouble()) {
list.add(scanner.nextDouble());
}
scanner.close();
System.out.println(list);
}
}
So i'm working on a bowling calculator assignment that takes a series of inputs and calculates a score. The test input provided by my instructor has a number of test cases which denote how many strings will need to be computed to scores. The problem I am having is that I am not able to get all 3 strings (there are 3 test cases) into a single string, separated on different lines.
This is what the input is:
3
--,--,--,--,--,--,--,--,--,--
X,X,X,X,X,X,X,X,X,XXX
X,13,X,81,5/,X,18,33,X,X36
I am trying to get it to be formatted as such:
--,--,--,--,--,--,--,--,--,--
X,X,X,X,X,X,X,X,X,XXX
X,13,X,81,5/,X,18,33,X,X36
However, when I run my code I get this as the output:
--,--,--,--,--,--,--,--,--,--
X,X,X,X,X,X,X,X,X,XXX
X,13,X,81,5/,X,18,33,X,X36
Here is what I've got so far.
import java.io.*;
import java.util.*;
public class Bowling {
public static void main(String[] args) throws FileNotFoundException {
File inFile = new File("input.txt");
Scanner scanFile = new Scanner(inFile);
int tc = scanFile.nextInt();
String N = "";
for (int i=0; i < tc; i++)
N += scanFile.next();
System.out.println(N);
}
}
**UPDATE: Thank you everyone for the answers, I have learned quite a bit because of your responses. At the time of asking this question I was tied up on this problem and was not thinking straight. I looked over my code again and realized all i had to do was add this line before the strings were added to the variable:
N += "\n";
Again, thanks to all those who commented.
I recommend using a StringBuilder if you are going to be concating a lot of String's. But on every iteration of the loop, you can append a newline character:
StringBuilder sb = new StringBuilder();
for (int i=0; i < tc; i++) {
sb.append(scanFile.next());
sb.append("\n");
}
System.out.println(sb);
It is possible to:
• Make a String[] array
• Use dividers, like \t
• Use other methods
Also, don't forget to say that you want us to tell you how to use newline characters.
I'd love to use StringJoiner in your case,I totally agree with #GBlodgett's answer. But this too can serve as an alternate.
From the javadoc,
StringJoiner is used to construct a sequence of characters separated
by a delimiter
which exactly suits your case. Your loop reads as,
StringJoiner sj= new StringJoiner("\n"); // Here, "\n" is the delimiter between every join.
for (int i=0; i < tc; i++){
sj.add(scanFile.next());
}
System.out.println(sj.toString());
Also, this avoids appending unnecessary newline after the last appended line.
I've found a bug in your code that explains why the output is in one line.
The command System.out.println(N) should be inside the for loop.
The variable N is unnecessary - please omit it.
There is another problem of resource leakage in your code, because the Scanner was never closed. The scanner should be closed using the auto closeable mechanism (by using try with resource statement).
I propose the following code to solve the problem:
public static void main(String[] args) throws FileNotFoundException {
File inFile = new File("input.txt");
try (Scanner sc = new Scanner(inFile)){
int tc = sc.nextInt();
for (int i=0; i < tc; i++) {
System.out.println(sc.next());
}
}
}
So I have an assignment from an online course to create a program that can scan a massive document. What this document contains is hundreds of pairs of letters that include GB GG BB BG and each set of two letters has its own line. What I have to do is figure out how many lines there are and then figure out how many of the different sets of two letters there are. I've attempted the code but I am currently stuck. The code that I have compiles but when I run it in BlueJ an output window doesn't even pop up. This is what I have so far:
/**
* This program sorts through a file and
* determines the composition of various families.
* Timothy Pierce
* 1/2/2016
*/
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class Family
{
public static void main(String [ ] args) throws IOException
{
boolean isTwoBoys;
boolean isTwoGirls;
boolean isBoyGirl;
int twoBoysCounter = 1;
int twoGirlsCounter = 1;
int boyGirlCounter = 1;
String line = "";
Scanner inFile = new Scanner(new File ("C:\\Users\\TEM\\Desktop\\Projects\\Family\\Document\\test1.txt"));
while (inFile.hasNextLine ())
{
isTwoBoys = (line.equals("BB"));
isTwoGirls = (line.equals("GG"));
isBoyGirl = (line.equals("BG")||line.equals("GB"));
if(isTwoBoys)
{
twoBoysCounter++;
}
else if(isTwoGirls)
{
twoGirlsCounter++;
}
else if(isBoyGirl)
{
boyGirlCounter++;
}
}
System.out.println();
System.out.println("Two Boys: " + twoBoysCounter);
System.out.println("One Boy One Girl: " + boyGirlCounter);
System.out.println("Two Girls: " + twoGirlsCounter);
inFile.close();
}
}
I've tried for several hours but I cant seem to get it to work. I haven't even been able to count how many line there are. Any help would be very appreciated! Thanks!
You never read the next line, so you're stuck in an infinite while loop
I suggest that you look into Files.readAllLines function for this case.
It loads all the lines in a List over which you can easily iterate and do what you need.
Example: Files.readAllLines(Paths.get("C:\\Users\\TEM\\Desktop\\Projects\\Family\\Document\\test1.txt", Charsets.default()) will load what you need
your while loop is inifinite as stated above since inFile.hasNextLine () is a boolean statement that returns true or false but it doesnt advance the scanner to the next line, you need to add to each of the if statements a :
inFile.nextLine() //advance the inputstream
Skipping over the "no readNextLine" issue pointed out by others, your basic technique is terrible.
Use a Map<String, Integer>.
Store the character pair as the key.
Every time you read a new pair,
attempt to retrieve it from the map.
If you get null, then the pair does not already have a counter,
so store 1 as the value.
If you get a non-null value, add 1 and store the new count.
When finished reading,
you have a map of character pairs to number of times encountered.
I am writing a CSVParser program that seperates words at commas. I am currently trying to find and record the longest word that appears in the file. Here is my class.
import csv.CSVParser;
import java.io.*;
import java.util.*;
public class RecordFormatter {
public static void main (String[] args) {
CSVParser parser = new CSVParser(new File (args[0]));
while (parser.hasNextLine()) {
ArrayList<String> ls = parser.getNextLine();
for (int i = 0; i<ls.size(); i++) {
System.out.print("|" + ls.get(i) + " ");
}
System.out.print("|");
System.out.println();
}
CSVParser parser1 = new CSVParser(new File (args[0]));
ArrayList<Integer> maxCol = new ArrayList<Integer>();
while (parser1.hasNextLine()) {
ArrayList<String> ls1 = parser1.getNextLine();
for (int i = 0; i<ls1.size(); i++) {
maxCol.add(ls1.get(i)); //Here is where my bug occurs.
}
}
}
}
I have created two CSVParsers and am trying to use the second of the two to record the length. I tried (as you can see above) storing the int length value of each word into another Arraylist, but I can't seem to get it to work. Any help would be much appreciated.
Without giving the solution, since this is homework...
Notice that you are keeping every length value rather than comparing the current length against a previous value to determine if it is longer and only then keeping it.
Seems like you need just a single maxLength Integer (or int) rather than a list since you just want the longest single word.
If you wanted the longest word per line, a List might then be appropriate.
Another option would be to use a SortedList and get the largest value (last value) in the list.
What I'm trying to do is create lots of random files but I'm just completely lost. The code below just doesn't work, I'm wondering why it doesn't work and what can i do to fix it.
import java.io.*;
import java.util.*;
public class main {
public static void main(String arg[]){
Random rn = new Random();
int randn = 1+rn.nextInt(999999990);
String I_S = Integer.toString(randn);
Formatter file;
try{
for(int i = 0; i < 9999999; i++){
file = new Formatter("%s.txt", I_S);
}
}
catch(Exception ex){
System.err.println("Error");
}
}
}
By just generating random numbers, you may end up creating / overwriting the same file multiple times. To have an absolutely unique set, do something like this:
final int MAX = 9999999;
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < MAX; i++) {
list.add(i);
}
Collections.shuffle(list);
for (int i = 0; i < MAX; i++) {
// create files here
}
How to create multiple files, generating a random name for each file.
You probably want to have a look at File.createTempFile.
Looking at your code, you probably want something like
Random rn = new Random();
String file;
for (int i = 0; i < 100; i++)
file = String.format("%i.txt", 1+rn.nextInt(999999990));
I'm not sure exactly what you expect this code to achieve, but right now it effectively does nothing.
You're looping many, many times creating an instance of Formatter each time. This is not a file; instead, it's a class that knows how to replace tokens in strings to create other strings.
I think you're confused by the description of the constructor you're calling and the purpose of the class as a whole. The constructor takes as its first argument the name of the file to use for output - in your case, this will always be %s.txt. The second argument is the name of a supported charset to use for encoding the String to the file.
This code will always fail because:
Your I_S variable, e.g., "56437890" is not a valid encoding (whereas "UTF-8" would be). Hence the constructor will probably throw an exception when trying to work out the encoding scheme.
Even if the charset was miraculously right, you're still trying to write to the same file (%s.txt) every time, so you wouldn't get the desired multi-file behaviour.
This string may not even be a valid filename, depending on your OS, and so if the Formatter tries to create the file it will throw an exception.
If both arguments miraculously work out, you're still not actually doing anything with the formatter, so it doesn't have anything to write out to the file which thus may not be created.
Finally, you're not updating your random variable (I_S) in the loop - it gets set once, and then maintains the same value forever. So even if all the above problems weren't issues, you'd still create the same (single) randomly-named file over and over and over again.
And as I noted in the comments, when it fails, you're catching and swallowing the exception so you have absolutely no way of knowing what went wrong.
Fundamentally I think you're confused about the purpose of the Formatter class, and since I don't know what you're trying to achieve (should the files be empty? Have specific text in?) I can't suggest something which definitely works. However, if you just want to create empty files, try something like this inside your loop:
String filename = "%s.txt".format(I_S);
File file = new File(filename);
file.createNewFile();
// Add some logic to update the random variable here!
As a final point, adarshr's answer is entirely right that you stand a nontrivial chance of repeating random numbers, so you won't get exactly as many files as you expect. The answer goes on to describe a good way to avoid this, and it's worth following.
You may want to look into writing something more like this:
void Write()
{
try {
for(int i = 0; i < MAX_FILES; i++) {
FileWriter outFile = new FileWriter("C:\File" + i.toString() + ".txt");
PrintWriter out = new PrintWriter(outFile);
// Write text to file
out.println("This is line 1");
out.println("This is line 2");
out.print("This is line3 part 1, ");
out.println("this is line 3 part 2");
out.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
// obviously this requires a import java.io.*; at the top of the class
Source: http://www.abbeyworkshop.com/howto/java/writeText/index.html