I am making a program in which it encrypts words into some kind of secret message, but I keep on getting an error. Yes, I know the code is ugly... but I am a beginner.
Here is my main.
public class Main {
public static void main (String args []){
String message;
message = JOptionPane.showInputDialog("Give me something to crypt!");
Crypt secret = new Crypt();
secret.CyptedMessage(message);
}
}
Here is my class.
public class Crypt {
String letter[];
String message;
public Crypt(){
message = "";
letter[0]="A";
letter[1]="B";
letter[2]="C";
letter[3]="D";
letter[4]="E";
letter[5]="F";
letter[6]="G";
letter[7]="H";
letter[8]="I";
letter[9]="J";
letter[10]="K";
letter[11]="L";
letter[12]="M";
letter[13]="N";
letter[14]="O";
letter[15]="P";
letter[16]="Q";
letter[17]="R";
letter[18]="S";
letter[19]="T";
letter[20]="U";
letter[21]="V";
letter[22]="W";
letter[23]="X";
letter[24]="Y";
letter[25]="Z";
letter[26]=" ";
}
int getRandomCrypt(){
//Random number 1 to 25
int x;
x=(int)(1 + Math.random()*25);
return x;
}
int checkLetter(String subMessage){
//Checks letters
boolean b = false;
int i=0;
while (b = false){
if (i == 27){
i=0;
if (subMessage == letter[i])
return i;
else
i++;
}
}
return 0;
}
void CyptedMessage(String message){
String CyptedMessage = null;
String message1;
for (int i = 0; i < message.length(); i++){
int number = checkLetter(message.substring(i, i+1));
message1 = letter[number + getRandomCrypt()];
if (number + getRandomCrypt()>26){
message1 = letter[i-27];
}
CyptedMessage += message1;
}
System.out.print(CyptedMessage);
}
}
When I run this I get...
Exception in thread "main" java.lang.NullPointerException
at Crypt.<init>(Crypt.java:9)
at Main.main(Main.java:9)
As Serge pointed out, String letter[] is an array declaration, not an initialization. You need to then initialize it to define an exact size.
public Crypt(){
letter = new String[27]; //define array
message = "";
letter[0]="A";
letter[1]="B";
letter[2]="C";
letter[3]="D";
letter[4]="E";
letter[5]="F";
letter[6]="G";
letter[7]="H";
letter[8]="I";
letter[9]="J";
letter[10]="K";
letter[11]="L";
letter[12]="M";
letter[13]="N";
letter[14]="O";
letter[15]="P";
letter[16]="Q";
letter[17]="R";
letter[18]="S";
letter[19]="T";
letter[20]="U";
letter[21]="V";
letter[22]="W";
letter[23]="X";
letter[24]="Y";
letter[25]="Z";
letter[26]=" ";
}
Edit: forgot ;
And others beat me :P
You are not initializing your String letter[]; and directly adding values into it
do this in your constructor
letter = new String[size];
or do this in starting String letter[] = new String[size];
and in your case size is 27
You need to initialize you array ans not just define it.
String letter[] = new String[27];
Also you can put a NPE check before using the array data
if(letter[number + getRandomCrypt()] != null)
message1 = letter[number + getRandomCrypt()];
Your String letter[]; is not instantiated.
add letter = new String[size]; in your Constructor of Crypt before initialization.
In class Crypt, you declare a string array named letters, but you do not initialize it when you use it. That is why you encounter a NullPointerException.
Initilize it before you use it.
public Crypt(){
**letter= new String[27];**
letter[0]="A";
letter[1]="B";
... ...
}
Related
So I am trying to create an object array that from a text file. The objects I am placing in the array are people objects with 4 parameters. 1st name, last name, an ID number and a height. The text file has a certain number of lines and each element is separated by an exclamation mark. I am trying to take each of the 4 elements to create an object and then place that object into an object array. Here is my code up until now. Also because I am new to java, there is not a lot that I know so the code needs to be simple.
import java.io.File;
import java.io.IOException;
import java.util.*;
public class Participants {
public static void main(String[] args) {
String array[] = new String[35];
Object participants[] = new Object[35];
int count = 0;
int counter = -1;
try {
File myFile1 = new File("Participants.txt");
Scanner scan1 = new Scanner(myFile1);
while (scan1.hasNext()) {
counter++;
array[counter] = scan1.next();
}
} catch (IOException ioe) {
System.out.println("The file can not be read");
}
for (int i = 0; i < array.length; i++) {
StringTokenizer st = new StringTokenizer(array[i], "!");
while (st.hasMoreTokens()) {
People person = new People(st.nextToken(), st.nextToken(), st.nextToken(),
st.nextToken());
participants[i] = person;
}
}
}
}
I commented that your code basically looks okay. There are some problems I spotted, and I think you may be running into them. You are probably getting a
Exception in thread "main" java.lang.NullPointerException
at java.util.StringTokenizer.<init>(Unknown Source)
at java.util.StringTokenizer.<init>(Unknown Source)
at Participants.main(Participants.java:22)
because arrays[i] is empty in
StringTokenizer st = new StringTokenizer(array[i], "!");
which is because you allocate 35 entries:
String array[] = new String[35];
and the file contains less lines than that. At least, that's what I'm getting it with this input file:
A!B!C!D
E!F!G!H
I!J!K!L
which is to be expected.
If I change the first line of the input file into
A!B!C
I get
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(Unknown Source)
at Text2ObjArray.main(Text2ObjArray.java:28)
which is because you only check once for a token, but then proceed to read four:
while (st.hasMoreTokens()) {
Person person = new Person(st.nextToken(), st.nextToken(), st.nextToken(), st.nextToken());
I'll update with a solution, if it is needed, but here are two suggestions:
1) use an ArrayList instead of an array[]:
2) Check what you parse: make sure there are 4 tokens per line, and deal with the exceptional case that they are not 4.
UPDATE
Basically, there's nothing wrong with your program. You already know "
How to put values from a text file into an object array in java?".
Your program runs just fine if you feed it a file with exactly 35 lines containing at least 3 exclamation marks each. If not, it throws the appropriate exceptions:
a NullPointerException if there are less than 35 lines and
an ArrayIndexOutOfBoundsException if there are more, and
a NoSuchElementException if there are less than 3 exclamation marks on any of the lines.
(Unless, there is a problem is in the People class which is unlikely if it is a POJO).
Your code only needed a few minor changes to make it work for files with other content. I've kept it simple:
import java.io.File;
import java.io.IOException;
import java.util.*;
public class Text2ObjArray {
public static void main(String[] args) {
Person[] participants = loadFile(new File(args.length > 0
? args[0] : "Participants.txt"));
for (Person p : participants)
System.out.println("Participant: " + p);
}
I split off main merely as good practice - see 'top-down' and 'bottom-up'.
To address the NullPointerException and ArrayIndexOutOfBoundsException We'll use an ArrayList instead of an array[] to keep track of the lines we read from the file. The advantage of an ArrayList is that it can grow and shrink, which is useful if you don't know for sure if "Participants.txt" always contains 35 lines.
Also it saves us from replacing our array with a bigger one when it's full. It's a cheap, handy upgrade from an array[], and all that has changed is writing
array.get(i) instead of array[i]
array.set(i,foo) instead of array[i]=foo and
array.add(foo) instead of array[counter++]=foo and
array.size() instead of array.length. It is a dynamic array, so you can insert into any position, remove etc.
private static Person[] loadFile(File file) {
List<String> lines = new ArrayList<>();
try (Scanner scan1 = new Scanner(file)) {
while (scan1.hasNext())
lines.add(scan1.next());
} catch (IOException e) {
System.out.println("File read error: " + e.getMessage());
}
This section is changed only in that it reads up to 4 tokens, dealing with the NoSuchElementException:
Person participants[] = new Person[lines.size()];
for (int i = 0; i < lines.size(); i++) {
StringTokenizer st = new StringTokenizer(lines.get(i), "!");
String[] fields = new String[4];
for (int k = 0; k < fields.length && st.hasMoreTokens(); k++)
fields[k] = st.nextToken();
participants[i++] = new Person(fields[0], fields[1], fields[2], fields[3]);
}
return participants;
}
}
To run it successfully you'll need to replace Person to People or use this Person class:
public class Person {
private String id;
private String lName;
private String fName;
private String height;
public Person(String id, String fName, String lName, String height) {
this.id = id;
this.fName = fName;
this.lName = lName;
this.height = height;
}
public String toString() {
return "Person[" + id + ": " + lName + ", " + fName + ", " + height + "]";
}
}
I hope that this has been helpful.
I am continuing to get this error. Now I have gotten it for my SortSearchUtil. I've tried to do some debugging but can fix the issue. The error reads:
----jGRASP exec: java PostOffice
Exception in thread "main" java.lang.NullPointerException
at SortSearchUtil.selectionSort(SortSearchUtil.java:106)
at PostOffice.sortLetters(PostOffice.java:73)
at PostOffice.main(PostOffice.java:15)
----jGRASP wedge: exit code for process is 1.
----jGRASP: operation complete.
line 106 of selection Sort is:
if (array[indexSmallest].compareTo(array[curPos]) > 0)
I don't know what could be wrong with my method. It's a standard method that was given to me by my instructor. I've tried to debug my program but I'm pretty stuck. Here is the method that the error is originating from, selectionSort:
public static void selectionSort(Comparable[] array)
{
int curPos, indexSmallest, start;
Comparable temp;
for (start = 0; start < array.length - 1; start++)
{
indexSmallest = start;
for (curPos = start + 1; curPos < array.length; curPos++)
if (array[indexSmallest].compareTo(array[curPos]) > 0)
{
indexSmallest = curPos;
}
// end for
temp = array[start];
array[start] = array[indexSmallest];
array[indexSmallest] = temp;
} // end for
}
The sort method is at the bottom which calls SortSearchUtil.selectionSort of this Post Office Method:
import java.util.*;
import java.io.*;
public class PostOffice
{
private final int max = 1000;
private Letter [] ltrAra = new Letter[max];
private int count;
public static void main(String [] args)
{
PostOffice postOffice = new PostOffice();
postOffice.readLetters("letters.in");
postOffice.sortLetters();
postOffice.printLetters();
}
public PostOffice()
{
Letter [] Letters = ltrAra;
this.count = 0;
}
public void readLetters(String filename)
{
int count = 0;
int iWork = 0;
Scanner fin = new Scanner(filename);
String toName, toStreet, toCity, toState, toZip;
String fromName, fromStreet, fromCity, fromState, fromZip, temp;
double weight;
String sWork;
fin = FileUtil.openInputFile(filename);
if (fin != null)
{
while (fin.hasNext())
{
toName = fin.nextLine();
toStreet = fin.nextLine();
sWork = fin.nextLine();
iWork = sWork.indexOf(",");
toCity = sWork.substring(0, iWork);
iWork = iWork + 2;
toState = sWork.substring(iWork, iWork + 2);
iWork = iWork + 3;
toZip = sWork.substring(iWork);
fromName = fin.nextLine();
fromStreet = fin.nextLine();
sWork = fin.nextLine();
iWork = sWork.indexOf(",");
fromCity = sWork.substring(0, iWork);
iWork = iWork + 2;
fromState = sWork.substring(iWork, iWork + 2);
iWork = iWork + 3;
fromZip = sWork.substring(iWork);
sWork = fin.nextLine();
weight = Double.parseDouble(sWork);
ltrAra[count] = new Letter(toName, toStreet, toCity, toState, toZip, fromName, fromStreet, fromCity, fromState, fromZip, weight);
count++;
}
fin.close();
}
}
public void sortLetters()
{
SortSearchUtil.selectionSort(ltrAra);
}
public void printLetters()
{
for (Letter ltr : ltrAra)
{
System.out.println(ltr);
System.out.println();
}
}
}
My file looks like this "letters.in":
Stu Steiner
123 Slacker Lane
Slackerville, IL 09035
Tom Capaul
999 Computer Nerd Court
Dweebsville, NC 28804-1359
0.50
Tom Capaul
999 Computer Nerd Court
Dweebsville, NC 28804-1359
Chris Peters
123 Some St.
Anytown, CA 92111-0389
1.55
Obviously you get a NPE because:
You initialize ltrAra as array of 1000 items, but you read in less than 1000 items within method readLetters(). So at the end of this array some null references remain un-initialized (remember array-creation does itself not set the single items to any objects). Therefore following sorting-method gets some null-references => NPE.
Suggested solution:
You should use an ArrayList instead of an array because that will automatically prevent you from accessing too much items due to internal range check.
In addition to the above answer that Meno has well stated, you need to understand when you get a Null pointer Exception.
your error-line : if (array[indexSmallest].compareTo(array[curPos]) > 0)
If we get NPE in this line, it is obvious that array[indexSmallest] is null
And when you invoke an action on null, you get NPE. Hope this helps you to debug, down the line.
Also, One of the main reasons when we choose ArrayList over Arrays is when we do not know the length of the array.
One more suggestion, you can create an ArrayList and then convert to Arrays if you want to stick with Arrays
To convert ArrayList of any class into array, Convert T to the respective class. For eg: if you want String array, convert T to 'String'
List<T> list = new ArrayList<T>();
T [] students = list.toArray(new T[list.size()]);
I´ve got a logic problem with a hangman project, it takes an letter from the user and searches if that letter is contained within the secret word. The problem is the way I´ve programmed it, if there are several occurrences of the letter the user guessed within the secret word. it will just go through and denote them all. Which is not what I want, I only want it to update the status of correctly guessed letter one at a time.
I tried some different stuff like setting a break after status(guessCh, but then the iterator will just go to the first occurrence where the letters match and stop there.
any simple fix to this?
private void compare(String str)
{
guessCh = str.charAt(0);
char secretCh = '0';
for (int i = i2; i < secretWord.length(); i++) // Cuts the secret word into individual chars to process.
{
secretCh = secretWord.charAt(i);
// Compare the two strings.
if (guessCh == secretCh)
{
status(guessCh, i); // Sends the letter & placement to status().
}
}
}
n
private String status(char guessCh, int placement)
{
/* Update and return status. */
if (guessCh >='A' && guessCh <= 'Z')
{
status = new StringBuffer(status).deleteCharAt(placement).toString();
status = new StringBuffer(status).insert(placement,guessCh).toString();
println("That guess is correct.");
canvas.displayWord(status);
return status;
}
return status;
}
You could test for a prior solution using your status variable from inside your compare method.
if (guessCh == secretCh && status.charAt(i) != secretCh)
{
status(guessCh, i);
break;
}
From what I can read (and understand), the basic problem you're facing is caused by the for loop in the compare method.
(Note, my examples are case sensitive, you will need to take that into account)
There are two basic approaches I can suggest...
The first is, match ALL occurrences with a single check...
private char guessCh;
private String secretWord;
private String status;
private String secretBuffer;
public TestStringCompare() {
secretWord = "This is a test";
// This is a copy of the secret word, this ensures that
// we always have a copy of the original.
secretBuffer = secretWord;
status = "______________";
guessCh = 'i';
compare("i");
}
private void compare(String str) {
while (secretBuffer.contains(str)) {
int foundAt = secretBuffer.indexOf(str);
status(str.charAt(0), foundAt);
// We want to remove the "guess" from our check string
// so it doesn't cause a false positive in the future
StringBuilder sb = new StringBuilder(secretBuffer);
sb.replace(foundAt, foundAt + 1, "_");
secretBuffer = sb.toString();
System.out.println(secretBuffer);
}
}
private String status(char guessCh, int placement) {
/* Update and return status. */
if (Character.isLetter(guessCh)) {
status = new StringBuffer(status).deleteCharAt(placement).toString();
status = new StringBuffer(status).insert(placement, guessCh).toString();
System.out.println("That guess is correct.");
System.out.println(status);
}
return status;
}
Which would produce:
That guess is correct.
__i___________
Th_s is a test
That guess is correct.
__i__i________
Th_s _s a test
or, replace the first occurrence of the guess (which from what I understand is what you're after)
public class TestStringCompare {
public static void main(String[] args) {
new TestStringCompare();
}
private char guessCh;
private String secretWord;
private String status;
private String secretBuffer;
public TestStringCompare() {
secretWord = "This is a test";
secretBuffer = secretWord;
status = "______________";
guessCh = 'i';
compare("i");
}
private void compare(String str) {
if (secretBuffer.contains(str)) {
int foundAt = secretBuffer.indexOf(str);
status(str.charAt(0), foundAt);
// Some where here you need to remove the "guess" character
// to ensure that it doesn't get repeated...
StringBuilder sb = new StringBuilder(secretBuffer);
sb.replace(foundAt, foundAt + 1, "_");
secretBuffer = sb.toString();
System.out.println(secretBuffer);
}
}
private String status(char guessCh, int placement) {
/* Update and return status. */
if (Character.isLetter(guessCh)) {
status = new StringBuffer(status).deleteCharAt(placement).toString();
status = new StringBuffer(status).insert(placement, guessCh).toString();
System.out.println("That guess is correct.");
System.out.println(status);
}
return status;
}
}
Which would produce this...
That guess is correct.
__i___________
Th_s is a test
I am guessing this is homework of some sort - but anyway, why not use indexOf
I wish to:
Reading in two files
Split the files into individual strings
Compare the two string lists and retrieve strings that are unique to a file.
At the moment I am running in to the problem of finding a way to call the two methods used to call in the files (one for each file) to the same method in order to be compared.
Both methods use a try-catch-while statement and if I try to read all of the entries after the while statement only a single is shown and not the entire list.
Is there a way to send parts of both methods as parameter to a single new method?
Here is the code for the program. I know that there are problems with the way that I am doing the program, but I am only doing it the way that I was taught.
File mainEmails = new File("Testrun.txt");
Scanner inputScanner = null;
int counter = 1;
String fullName = null;
String position = null;
String companyName = null;
String telNumber = null;
String emailAddress = null;
try
{
inputScanner = new Scanner(mainEmails);
}
catch(FileNotFoundException e)
{
System.out.println("File has not been found.");
}
while (inputScanner.hasNextLine())
{
String nextLine = inputScanner.nextLine();
String [] splitFile = nextLine.split(",");
for (int i = 0; i <splitFile.length;i++)
{
if(i==0)
{
fullName = splitFile[0];
}
else if(i==1)
{
position = splitFile[1];
}
else if(i==2)
{
companyName = splitFile[2];
}
else if(i==3)
{
telNumber = splitFile[3];
}
else if(i==4)
{
emailAddress = splitFile[4];
}
else if(splitFile[i] == null)
{
System.out.println("You have failed!");
}
}
}
public static void deletionList()
{
File deletionEmails = new File("Testrun1.txt");
Scanner inputScanner1 = null;
String deletionfullName = null;
String deletionposition = null;
String deletioncompanyName= null;
String deletiontelNumber = null;
String deletionemailAddress = null;
try
{
inputScanner1 = new Scanner(deletionEmails);
}
catch(FileNotFoundException e)
{
System.out.println("File has not been found.");
}
while (inputScanner1.hasNextLine())
{
String deletionnextLine = inputScanner1.nextLine();
String [] deletionsplitFile = deletionnextLine.split(",");
for (int i = 0; i <deletionsplitFile.length;i++)
{
if(i==0)
{
deletionfullName = deletionsplitFile[0];
}
else if(i==1)
{
deletionposition = deletionsplitFile[1];
}
else if(i==2)
{
deletioncompanyName = deletionsplitFile[2];
}
else if(i==3)
{
deletiontelNumber = deletionsplitFile[3];
}
else if(i==4)
{
deletionemailAddress = deletionsplitFile[4];
}
else if(deletionsplitFile[i] == null)
{
System.out.println("You have failed!");
}
}
}
}
What I am trying to do is to take the fullName, emailAddress from the first split and deletionfullName and deletionemailAddress from the second split and compare the first and second of each, respectively. Each file will have a number of fields in it, and I am only interested in the fullName and emailAddress fields.
It is quite confusing to understand how you are trying to implement your solution, so may I suggest you look at a different way of doing the whole read-and-compare process. For example, I would suggest doing something like this... (in psuedocode)
public void compareFiles(String file1, String file2){
// Read the lines of each file into String[] arrays
String[] file1Lines = readAndSplitIntoLines(file1);
String[] file2Lines = readAndSplitIntoLines(file2);
// compare the lines
for (int x=0;x<file1Lines.length;x++){
for (int y=0;y<file2Lines.length;y++){
if (file1Lines[x].equals(file2Lines[y])){
// match. set it to null
file1Lines[x] = null;
file2Lines[y] = null;
// break out of the inner loop and start comparing the next line
break;
}
}
// remove the duplicates (which are now null values), creating a smaller array of uniques.
String[] newFile1 = shrinkArrayByRemovingNulls(file1Lines);
String[] newFile2 = shrinkArrayByRemovingNulls(file2Lines);
}
Besides the fact that your question is not very clear, you have at least one glaring problem:
DO NOT use exception handling for logic! Exception handling should be only for exceptions.
Secondly, think about what you are really looking to do. In pseudocode it would look something like this:
list1 = split(file(name1).read())
list2 = split(file(name2).read())
list3 = unique(list1, list2)
What does your code look like?
Over the past couple of weeks I've read through the book Error Control Coding: Fundamentals and Applications in order to learn about BCH (Bose, Chaudhuri, Hocquenghem) Codes for an junior programming role at a telecoms company.
This book mostly covers the mathematics and theory behind the subject, but I'm struggling to implement some of the concepts; primarily getting the next n codewords.I have a GUI (implemented through NetBeans, so I won't post the code as the file is huge) that passes a code in order to get the next n numbers:
Generating these numbers is where I am having problems. If I could go through all of these within just the encoding method instead of looping through using the GUI my life would be ten times easier.
This has been driving me crazy for days now as it is easy enough to generate 0000000000 from the input, but I am lost as to where to go from there with my code. What do I then do to generate the next working number?
Any help with generating the above code would be appreciated.
(big edit...) Playing with the code a bit more this seems to work:
import java.util.ArrayList;
import java.util.List;
public class Main
{
public static void main(final String[] argv)
{
final int startValue;
final int iterations;
final List<String> list;
startValue = Integer.parseInt(argv[0]);
iterations = Integer.parseInt(argv[1]);
list = encodeAll(startValue, iterations);
System.out.println(list);
}
private static List<String> encodeAll(final int startValue, final int iterations)
{
final List<String> allEncodings;
allEncodings = new ArrayList<String>();
for(int i = 0; i < iterations; i++)
{
try
{
final int value;
final String str;
final String encoding;
value = i + startValue;
str = String.format("%06d", value);
encoding = encoding(str);
allEncodings.add(encoding);
}
catch(final BadNumberException ex)
{
// do nothing
}
}
return allEncodings;
}
public static String encoding(String str)
throws BadNumberException
{
final int[] digit;
final StringBuilder s;
digit = new int[10];
for(int i = 0; i < 6; i++)
{
digit[i] = Integer.parseInt(String.valueOf(str.charAt(i)));
}
digit[6] = ((4*digit[0])+(10*digit[1])+(9*digit[2])+(2*digit[3])+(digit[4])+(7*digit[5])) % 11;
digit[7] = ((7*digit[0])+(8*digit[1])+(7*digit[2])+(digit[3])+(9*digit[4])+(6*digit[5])) % 11;
digit[8] = ((9*digit[0])+(digit[1])+(7*digit[2])+(8*digit[3])+(7*digit[4])+(7*digit[5])) % 11;
digit[9] = ((digit[0])+(2*digit[1])+(9*digit[2])+(10*digit[3])+(4*digit[4])+(digit[5])) % 11;
// Insert Parity Checking method (Vandermonde Matrix)
s = new StringBuilder();
for(int i = 0; i < 9; i++)
{
s.append(Integer.toString(digit[i]));
}
if(digit[6] == 10 || digit[7] == 10 || digit[8] == 10 || digit[9] == 10)
{
throw new BadNumberException(str);
}
return (s.toString());
}
}
class BadNumberException
extends Exception
{
public BadNumberException(final String str)
{
super(str + " cannot be encoded");
}
}
I prefer throwing the exception rather than returning a special string. In this case I ignore the exception which normally I would say is bad practice, but for this case I think it is what you want.
Hard to tell, if I got your problem, but after reading your question several times, maybe that's what you're looking for:
public List<String> encodeAll() {
List<String> allEncodings = new ArrayList<String>();
for (int i = 0; i < 1000000 ; i++) {
String encoding = encoding(Integer.toString(i));
allEncodings.add(encoding);
}
return allEncodings;
}
There's one flaw in the solution, the toOctalString results are not 0-padded. If that's what you want, I suggest using String.format("<something>", i) in the encoding call.
Update
To use it in your current call, replace a call to encoding(String str) with call to this method. You'll receive an ordered List with all encodings.
I aasumed, you were only interested in octal values - my mistake, now I think you just forgot the encoding for value 000009 in you example and thus removed the irretating octal stuff.