scanner.hasNextInt() returns unexpected value - java

I'm very new in Java, and for practicing I'm trying to make a program that generates new, random words using some values (mostly letters). The program is meant to take these values from a text file. The next step is to define inventories (Arrays) that contain each letter of its kind (first by defining a variable (int) for the length of each array, and then filling each array with its proper letters (String)). While checking my progress, I realize that my code isn't updating the inventories lengths (cInv and vInv).
This is the relevant part of the code:
static File language;
static Scanner scanFile;
static Scanner scanInput = new Scanner(System.in);
static int cInv;
static int vInv;
//Getters go here
public static void setLanguage(File language) {Problem.language = language;}
public static void setCInv(int CInv) {Problem.cInv = cInv;}
public static void setVInv(int VInv) {Problem.vInv = vInv;}
//Asks for the file with the language values.
public static void takeFile() throws FileNotFoundException {
String route = scanInput.nextLine();
setLanguage(new File(route));
BufferedReader br;
br = new BufferedReader(new FileReader(language));
}
//Gathers the language values from the file.
public static void readFile() throws FileNotFoundException {
takeFile();
scanFile = new Scanner(language);
//Defines the inventory sizes. It seems the failure is here.
if (scanFile.hasNextInt()) {setCInv(scanFile.nextInt());}
if (scanFile.hasNextInt()) {setVInv(scanFile.nextInt());}
}
public static void main(String[] args) throws FileNotFoundException {
readFile();
//The following line is for checking the progress of my coding.
System.out.println(cInv);
}
This is the relevant part of the text file that it reads (or should be reading):
---Phonemes---
Consonants: 43
Vowels: 9
And it's output is 0
I've tried typing 43 at the very beginning of the file, and I've also tried typing the number in the input, but I keep getting 0 nevertheless. Does someone know what I'm missing or doing wrong?

First, change your assignments as you are reassigning the same static variables.
public static void setCInv(int CInv) {Problem.cInv = CInv;}
public static void setVInv(int VInv) {Problem.vInv = CInv;}
Second, you need to move across all tokens in the file to identify the numbers and update the respective variable.
//Gathers the language values from the file.
public static void readFile() throws FileNotFoundException {
takeFile();
scanFile = new Scanner(language);
int num = 0;
scanFile.nextLine(); //Skip ---Phonemes---
setCInv(getInt(scanFile.nextLine()));
setVInv(getInt(scanFile.nextLine()));
}
public static int getInt(String str){
System.out.println(str);
int num =0;
Scanner line = new Scanner(str);
//Splits the scanned line into tokens (accessed via next()) and search for numbers.
//Similar thing could have been done using String.split(token);
while(line.hasNext()){
try{
num = Integer.parseInt(line.next());
return num;
}catch(NumberFormatException e){}
}
return num;
}

Related

Why is the null error showing in my program; Stringtokenizer to array

This essentially is a small code I'm writting for practice that requires me to use StringTokenizer. I've done the same kind of programs before , but now when I store the strings in an array and try to print them it show's a null pointer exception. Any help?
import java.util.*;
public class board1
{
String key;
String m[];
//function to accept the sentence
void getsent()
{
Scanner in=new Scanner(System.in);
System.out.println("Enter a sentence terminated by'.' or '?'");
String take=in.nextLine();
StringTokenizer taken=new StringTokenizer(take);
int numtokens=taken.countTokens();
String m[]=new String[numtokens];
for(int i=0;i<m.length;i++)
{
m[i]=taken.nextToken();
}
for(int i=0;i<m.length;i++)
{
System.out.print(m[i]);
}
}
// function to display
void display()
{
System.out.println("The words seperately right now are:");
for(int i=0;i<m.length;i++)
{
System.out.print(m[i]+"\t");
System.out.println();
}
}
// main to get functions
public static void main(String args[])
{
board1 ob= new board1();
ob.getsent();
ob.display();
}
}
You're shadowing the variable m. Replace
String m[] = new String[numtokens];
with
m = new String[numTokens];
I think because you are shading properties. You have an array called m into which you are putting tokens in getSent, but display is using the m array defined in the class to which you haven't added anything.
Print out the size of m in display, this will show you that you are not adding anything to the property called m.

NullPointerException error, converting string[] to int[]

I'm running out of patience and needs this problem fixed. This program is intended to retrieve data from two text files as two string arrays, then use a mergesort algorithm to sort the results. My issue is during the conversion to an integer array. I return the array I created, and see that there is data stored. However, when running an loop and checking if any index is null, I find that the program believes them all to be null.
import java.io.IOException;
import java.nio.file.Files;
import java.io.File;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.*;
public class MergeInventories
{
public static File inv1 = new File("H:\\Senior Year\\CompSci\\Projects\\storeOneInv.txt");
public static File inv2 = new File("H:\\Senior Year\\CompSci\\Projects\\storeTwoInv.txt");
//the two text files I'm retrieving data from
public static String[] store1; //string array in question
public static String[] store2;
public static void header()
{
System.out.println("Keenan Schmidt");
System.out.println("AP Computer Science");
System.out.println("Merge Inventories");
System.out.println("...finally...");
}
public static void main() throws FileNotFoundException
{
header();
readFiles(inv1,store1); //converts file to string array
sort(); //converts string[] to int[]
//System.out.print(readFiles(inv1,store1));
//System.out.print(readFiles(inv2,store2);
}
public static String[] readFiles(File file, String[] store)
{
try {
Scanner scanner = new Scanner(file);
int i = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
scanner = new Scanner(file);
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
i++;
}
store = new String[i];
i = 0;
scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
store[i] = line;
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return store;
}
public static int[] sort()
{
int[] items = new int[store1.length];
for(int i = 0; i < store1.length; i++)
{
if(store1[i] != null) //this is the line where the error occurs
{
try{
items[i] = Integer.parseInt(store1[i].replaceAll("[^0-9]"," "));
} catch (NumberFormatException nfe) {};
}
}
return items;
}
private void mergeSort(String[] arr1, String[] arr2)
{
}
private void merge(int low, int med, int hi)
{
}
}
As azurefrog mentions in a comment, Java arrays are pass by value (the reference to the array) so that when you reassign the store variable in the method, the original array you passed in doesn't get the new reference assignment.
Since you want to re-use this method multiple times to make different arrays, I would suggest making a new array everytime inside the method. No need to pass it in.
static String[] readFiles(File file){
String[] store =null;
//rest of method this same
}
Then in your calling code:
store1 = readFiles(inv1);
store2 = readFiles(inv2);
You are getting a NullPointerException when trying to access store1 because you never give store1 a value other than null, because Java is pass-by-value.
You create a new array, but you only assign it to store, which is a local variable in readFiles(), and that assignment has no effect on the store1 variable.
You do return that value from your method, but you neglected to assign it in the invoking code.
Replace
readFiles(inv1,store1); //converts file to string array
with
store1 = readFiles(inv1,store1); //converts file to string array and saves it in store1
so that the created array is assigned to store1.
As dkatzel points out, this means that there is no longer any point in passing store1 into the method in the first place. It would be a good idea to follow his advice on cleaning up the method.
You can use a List at first because the file could be of unknown size, then convert the List to an Array (using toArray), and then you will know the length to which you should initialize the int array and your code can proceed as expected.
either change to this: store1 = readFiles(inv1,store1);
or in readFiles() use this.store1 instead

Why a Scanner cannot be reused?

I created a method called readFileAsScanner. It creates a file and a Scanner which attaches to the file. Then returns the Scanner.
Neverthelesss, I use it. The Scanner can be only used once. Why? Can I reset it by the reset() method of Scanner to make it reusable?
import java.io.*;
import java.util.*;
public class Lab10{
public static void main(String[] args)throws FileNotFoundException{
String[] words = readWords();
int i;
for(i=0;i<words.length;i++)
System.out.println(words[i]);
System.out.println(words.length);
}
public static String[] readWords()throws FileNotFoundException{
Scanner data = readFileAsScanner();
String[] words = new String[estimateWords(data)];
int i=0;
while(data.hasNext()){
System.out.println(data.next());
}
return words;
}
public static Scanner readFileAsScanner() throws FileNotFoundException{
Scanner input = new Scanner(System.in);
System.out.println("Input file name:");
//String fileName = input.next();
String fileName = "unsorted.txt";
Scanner data = new Scanner(new File(fileName));
return data;
}
public static int estimateWords(Scanner data){
int estimatedSize = 0;
while(data.hasNext()){
data.next();
estimatedSize++;
}
return estimatedSize;
}
}
You're consuming everything that you want to read in the estimateWords method call. By the time the scanner advances to the end of the file, you've read pretty much everything there is to read in the file, and the scanner's next call to hasNext() will return false.
You can fix this in one of two ways:
Open the file twice with a Scanner instance in each method call and pass in the filename, or
Open the file once, perform both a count and a reading of data in one method only.
I would opt for the latter, since it would be more straightforward and better practice (you typically don't see Scanner instances passed around).
Because the underlying stream is at end, and probably cannot be rewound or reset, and you can't attach a existing Scanner to another stream.

Why can't I print a variable that is provided by user inside a loop?

I apologize if the answer to this question is so obvious I shouldn't even be posting this here but I've already looked up the error compiling the following code results in and found no explanation capable of penetrating my thick, uneducated skull.
What this program is meant to do is get 2 integers from the user and print them, but I have somehow managed to mess up doing just that.
import java.util.Scanner;
public class Exercise2
{
int integerone, integertwo; //putting ''static'' here doesn't solve the problem
static int number=1;
static Scanner kbinput = new Scanner(System.in);
public static void main(String [] args)
{
while (number<3){
System.out.println("Type in integer "+number+":");
if (number<2)
{
int integerone = kbinput.nextInt(); //the integer I can't access
}
number++;
}
int integertwo = kbinput.nextInt();
System.out.println(integerone); //how do I fix this line?
System.out.println(integertwo);
}
}
Explanation or a link to the right literature would be greatly appreciated.
EDIT: I want to use a loop here for the sake of exploring multiple ways of doing what this is meant to do.
Remove the int keyword when using the same variable for the second time. Because when you do that, it is essentially declaring another variable with the same name.
static int integerone, integertwo; // make them static to access in a static context
... // other code
while (number<3){
System.out.println("Type in integer "+number+":");
if (number<2)
{
integerone = kbinput.nextInt(); //no int keyword
}
number++;
}
integertwo = kbinput.nextInt(); // no int keyword
And it needs to be static as well since you're trying to access it in a static context (i.e) the main method.
The other option would be to declare it inside the main() method but before your loop starts so that it'll be accessible throughout the main method(as suggested by "Patricia Shanahan").
public static void main(String [] args) {
int integerone, integertwo; // declare them here without the static
... // rest of the code
}
How about:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner kbinput = new Scanner(System.in);
System.out.println("Type in an integer: ");
int integerone = kbinput.nextInt();
System.out.println("Type another: ");
int integertwo = kbinput.nextInt();
System.out.println(integerone);
System.out.println(integertwo);
}
}

accessing variable within main method

I am very new to Java and writing this program to shuffle words and fix the suffle words. The following is my program. After I call mix(), I would like to be able to assign the output of word to team array within main.
For some reason, I can call mix() it works but I cannot access word which is in the shuffle function. Since I am in main and all these function within main, I thought I can access the variables. Any ideas what I am missing here?
import java.util.Scanner;
import java.io.*;
import java.util.*;
public class Project2
{
public static void main(String[] args)
{
System.out.println("Select an item from below: \n");
System.out.println("(1) Mix");
System.out.println("(2) Solve");
System.out.println("(3) Quit");
int input;
Scanner scan= new Scanner(System.in);
input = scan.nextInt();
//System.out.println(input);
if(input==1) {
mix();
System.out.println(word);
char team[]=word.toCharArray();
for(int i=0;i<team.length;i++){
System.out.println("Data at ["+i+"]="+team[i]);
}
}
else{
System.out.println("this is exit");
}
}
static void mix()
{
String [] lines=new String[1000];//Enough lines.
int counter=0;
try{
File file = new File("input.txt");//The path of the File
FileReader fileReader1 = new FileReader(file);
BufferedReader buffer = new BufferedReader(fileReader1);
boolean flag=true;
while(true){
try{
lines[counter]=buffer.readLine();//Store a line in the array.
if(lines[counter]==null){//If there isn't any more lines.
buffer.close();
fileReader1.close();
break;//Stop reading and close the readers.
}
//number of lines in the file
//lines is the array that holds the line info
counter++;
}catch(Exception ex){
break;
}
}
}catch(FileNotFoundException ex){
System.out.println("File not found.");
}catch(IOException ex){
System.out.println("Exception ocurred.");
}
int pick;
Random rand = new Random();
pick = rand.nextInt(counter ) + 0;
System.out.println(lines[pick]);
///scramble the word
shuffle(lines[pick]);
}
static void shuffle(String input){
List<Character> characters = new ArrayList<Character>();
for(char c:input.toCharArray()){
characters.add(c);
}
StringBuilder output = new StringBuilder(input.length());
while(characters.size()!=0){
int randPicker = (int)(Math.random()*characters.size());
output.append(characters.remove(randPicker));
}
String word=output.toString();
}
}
Return string value from shuffle() method using return statement:
static String shuffle(String input) {
// . . .
return output.toString();
}
...and then use it in mix:
String word = shuffle(lines[pick]);
But it is better to read basic java tutorials before programming.
In Java, variables cannot be seen outside of the method they are initialized in. For example, if I declare int foo = 3; in main, and then I try to access foo from another method, it won't work. From the point of view of another method, foo does not even exist!
The way to pass variable between methods is with the return <variable> statement. Once the program reaches a return statement, the method will quit, and the value after the return (perhaps foo) will be returned to the caller method. However, you must say that the method returns a variable (and say what type is is) when you declare that method (just like you need to say void when the method does not return anything!).
public static void main(String[] args){
int foo = 2;
double(foo); //This will double foo, but the new doubled value will not be accessible
int twoFoo = double(foo); //Now the doubled value of foo is returned and assigned to the variable twoFoo
}
private static int double(int foo){//Notice the 'int' after 'static'. This tells the program that method double returns an int.
//Also, even though this variable is named foo, it is not the same foo
return foo*2;
}
Alternatively, you could use instance variable to have variables that are accessible by all the methods in your class, but if you're new to Java, you should probably avoid these until you start learning the basics of object-oriented programming.
Hope this helps!
-BritKnight

Categories