beginner lexical analyzer in java - java

I am writing a lexical analyzer. I know it's super simple. It runs but whenever enter an input, the program treats it as invalid characters (even when they are supposed to be valid). What did I do wrong?
import java.util.*;
import java.util.Scanner;
public class LAnalyze{
public static int i;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String s;
System.out.println("Input something to lexically analyze: ");
s = input.next( );
int j = 1;
if( s.charAt(i)!='a'||s.charAt(i)!='b'||s.charAt(i)!='c'||s.charAt(i)!='d'||s.charAt(i)!='e'||s.charAt(i)!='f'||
s.charAt(i)!='g'||s.charAt(i)!='h'||s.charAt(i)!='i'||s.charAt(i)!='j'||s.charAt(i)!='k'||s.charAt(i)!='l'||
s.charAt(i)!='m'||s.charAt(i)!='n'||s.charAt(i)!='o'||s.charAt(i)!='p'||s.charAt(i)!='q'||s.charAt(i)!='r'||
s.charAt(i)!='s'||s.charAt(i)!='t'||s.charAt(i)!='u'||s.charAt(i)!='v'||s.charAt(i)!='w'||s.charAt(i)!='x'||
s.charAt(i)!='y'||s.charAt(i)!='z'||s.charAt(i)!='A'||s.charAt(i)!='B'||s.charAt(i)!='C'||s.charAt(i)!='D'||
s.charAt(i)!='E'||s.charAt(i)!='F'||s.charAt(i)!='G'||s.charAt(i)!='H'||s.charAt(i)!='I'||s.charAt(i)!='J'||
s.charAt(i)!='K'||s.charAt(i)!='L'||s.charAt(i)!='M'||s.charAt(i)!='N'||s.charAt(i)!='O'||s.charAt(i)!='P'||
s.charAt(i)!='Q'||s.charAt(i)!='R'||s.charAt(i)!='S'||s.charAt(i)!='T'||s.charAt(i)!='U'||s.charAt(i)!='V'||
s.charAt(i)!='W'||s.charAt(i)!='X'||s.charAt(i)!='Y'||s.charAt(i)!='Z'||s.charAt(i)!='0'||s.charAt(i)!='1'||
s.charAt(i)!='2'||s.charAt(i)!='3'||s.charAt(i)!='4'||s.charAt(i)!='5'||s.charAt(i)!='6'||s.charAt(i)!='7'||
s.charAt(i)!='8'||s.charAt(i)!='9'||s.charAt(i)!='-'||s.charAt(i)!='_'||s.charAt(i)!=' ') {
for (int i = 0; i < s.length(); i++) {
System.out.println("Token " + j + " = " + (s.charAt(i)));
j++;
}
}
else {
System.out.println("Invalid character(s) entered.. Program terminated!\n");
System.exit(0);
}
}
}

It would seem that it is impossible to get the results you say you are getting from this code. Your if statement is wrong. As it currently stands, it will always be true. A character will always be not equal to some character or not equal to another character. All of the != should be ==. I would also print out the bad character in the else part that reports it:
System.out.println("bad character " + s.charAt(i) +
" decimal value: " + (int) s.charAt(i));
Scanner does lexing on its own, that is, it returns tokens, not the whole string. I think you should use Console and get everything that was typed:
Console console = System.console();
s = console.readLine("Input something to lexically analyze: ");

import java.util.*;
public class Main {
static int i;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String s = "";
while (true) {
System.out.println("Input something to lexically analyze: ");
s = input.nextLine();
analize(s);
}
}
public static void analize(String s) {
String t = "-1234567890_ abcdefjhijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ";
char[] tt = t.toCharArray();
char[] cc = s.toCharArray();
int z = 1, i = 0, j = 0;
for (i = 0; i < cc.length; i++) {
for (j = 0; j < tt.length; j++) {
if (cc[i] == tt[j]) {
System.out.println("Token " + z + " = '" + cc[i] + "'");
z++;
break;
}
}
if (j > tt.length - 1) {
System.out.println("Invalid character " + (i + 1) + " ('" + cc[i] + "') entered...");
}
}
}
}

Related

Why is it that my character counter not increasing when the for loop goes?

I'm currently coding a program that takes in a string and a single character (if you decide to put a single one in that is) and (is supposed) to check how many times that character is in the string and at the end print out the amount of times it is in there. For some reason it isn't working and I would like some help; thank you!
import java.util.Scanner;
public class HowManyChars {
public HowManyChars() {
Scanner sc = new Scanner (System.in);
String askPhrase;
String askChar;
int charCounter = 0;
System.out.println("Enter a phrase");
askPhrase = sc.nextLine();
System.out.println("Enter a letter");
askChar = sc.nextLine();
for (int i = 0; i < askPhrase.length(); i++) {
if (askPhrase.substring(i, i + 1) == askChar) {
charCounter = charCounter + 1;
}
}
System.out.println("There are " + charCounter + " " + askChar + " in " + askPhrase);
}
}
I give credit for this answer to #Mushif, who correctly figured out the problem. Your current comparison logic is comparing a string against a character:
for (int i=0; i < askPhrase.length(); i++) {
// String char
if (askPhrase.substring(i, i + 1) == askChar) {
charCounter = charCounter + 1;
}
}
Try iterating the character set of the input word and then compare apples to apples:
for (int i=0; i < askPhrase.length(); i++) {
if (askPhrase.charAt(i) == askChar) {
charCounter = charCounter + 1;
}
}
You could also use an enhanced loop directly on the input's character set:
for (char chr : askPhrase.toCharArray()) {
if (chr == askChar) {
charCounter = charCounter + 1;
}
}
import java.util.Scanner;
public class HowManyChars {
public HowManyChars() {
Scanner sc = new Scanner (System.in);
String askPhrase;
char askChar;
char[] askChars;
int charCounter = 0;
System.out.println("Enter a phrase");
askPhrase = sc.nextLine();
askChars = askPhrase.toCharArray();
System.out.println("Enter a letter");
askChar = sc.next().charAt(0);
sc.close();
for (int i = 0; i < askChars.length; i++) {
if (Character.toLowerCase(askChar) == Character.toLowerCase(askChars[i])) {
charCounter ++;
}
}
System.out.println("There are " + charCounter + " " + askChar + " in " + askPhrase);
}
}

Guessing letter without having to capitalize input

I am new to this and I am having hard time with this code. I made a hangman game but I am having issues with the words that have a capital letter. If I don't input a capital letter the letter will not appear.
Here is my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Hangman {
static ArrayList<String> words = new ArrayList<>();
static boolean isCorrect;
private static Scanner input;
private static Scanner input2;
public static void main(String[] args) {
File filename = new File("hangman.txt");
if (!filename.exists()) {
System.out.println(filename.getAbsolutePath());
System.out.println(filename + " does not exist.");
System.exit(1);
}
try {
input2 = new Scanner(filename);
while (input2.hasNext()) {
words.add(input2.next());
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
input2.close();
input = new Scanner(System.in);
String playStarts = "y";
int wins = 0;
int loses = 0;
final int MAX_GUESSES = 11;
List<String> usedWords = new ArrayList<>();
while (playStarts.equals("y")) {
String word = getWord();
usedWords.add(word);
String secretWord = getSecretWord(word);
int missCount = 0;
while (!word.equals(secretWord)) {
System.out.print("(Guess) Enter a letter in word " + secretWord + " > ");
char ch = input.next().charAt(0);
if (!isAlreadyInWord(secretWord, ch)) {
secretWord = getGuess(word, secretWord, ch);
if (!isCorrect) {
System.out.print(ch + " is not in the word.");
missCount++;
System.out.println(" You missed "+ missCount + " times");
}
} else {
System.out.println(ch + " is already in word.");
}
if (missCount == MAX_GUESSES) {
System.out.println("You reached max number of guesses.");break;
}
}
if (missCount == MAX_GUESSES) {
loses++;
} else {
wins++;
}
System.out.println("The word is " + word + ". You missed " + missCount + " times");
System.out.println("Do you want to guess another word? Enter y or n >");
playStarts = input.next();
}
System.out.println("Number of wins is " + wins + ".");
System.out.println("Number of loses is " + loses + ".");
System.out.println("Used words:");
for (String word : usedWords) {
System.out.println(word);
}
input.close();
}
public static String getWord() {
return words.get((int) (Math.random() * words.size()));
}
public static String getSecretWord(String word) {
String hidden = "";
for (int i = 0; i < word.length(); i++) {
hidden += "*";
}
return hidden;
}
static public String getGuess(String word, String secretWord, char ch) {
isCorrect = false;
StringBuilder s = new StringBuilder(secretWord);
for (int i = 0; i < word.length(); i++) {
//I think the issue is in this section of the code:
if (ch == word.charAt(i) && s.charAt(i) == '*') {
isCorrect = true;
s = s.deleteCharAt(i);
s = s.insert(i, ch);
}
}
return s.toString();
}
public static boolean isAlreadyInWord(String secretWord, char ch) {
for (int i = 0; i < secretWord.length(); i++) {
if (ch == secretWord.charAt(i)) {
return true;
}
}
return false;
}
}
The code works fine but I just have an issue with the capitalization.
If your speculation be correct, the comparing the lowercase of both sides of the equation should fix the problem:
if (Character.toLowerCase(ch) == Character.toLowerCase(secretWord.charAt(i)) {
return true;
}
Better yet, you can lowercase the user character input when it actually happens:
System.out.print("(Guess) Enter a letter in word " + secretWord + " > ");
char ch = input.next().toLowerCase().charAt(0);
There are some handy functions in the Character class that you can use (Character.toUpperCase() and toLowerCase()) that can help you compare whether the characters match.
if (Character.toLowerCase(ch) == Character.toLowerCase(word.charAt(i)) && s.charAt(i) == '*') will always be checking two lowercase letters, so the case of neither ch or word.charAt(i) will matter.

How to return a string?

import java.util.*;
public class HangManP5
{
public static void main(String[] args)
{
int attempts = 10;
int wordLength;
boolean solved;
Scanner k = new Scanner(System.in);
System.out.println("Hey, what's your name?");
String name = k.nextLine();
System.out.println(name+ ", hey! This is a hangman game!\n");
RandomWord(word);
int len = word.length();
char[] temp = new char[len];
for(int i = 0; i < temp.length; i++)
{
temp[i] = '*';
}
System.out.print("\n");
System.out.print("Word to date: ");
while (attempts <= 10 && attempts > 0)
{
System.out.println("\nAttempts left: " + attempts);
System.out.print("Enter letter: ");
String test = k.next();
if(test.length() != 1)
{
System.out.println("Please enter 1 character");
continue;
}
char testChar = test.charAt(0);
int foundPos = -2;
int foundCount = 0;
while((foundPos = word.indexOf(testChar, foundPos + 1)) != -1)
{
temp[foundPos] = testChar;
foundCount++;
len--;
}
if(foundCount == 0)
{
System.out.println("Sorry, didn't find any matches for " + test);
}
else
{
System.out.println("Found " + foundCount + " matches for " + test);
}
for(int i = 0; i < temp.length; i++)
{
System.out.print(temp[i]);
}
System.out.println();
if(len == 0)
{
break; //Solved!
}
attempts--;
}
if(len == 0)
{
System.out.println("\n---------------------------");
System.out.println("Solved!");
}
else
{
System.out.println("\n---------------------------");
System.out.println("Sorry you didn't find the mystery word!");
System.out.println("It was \"" + word + "\"");
}
}
public static String RandomWord(String word)
{
//List of words
Random r = new Random();
int a = 1 + r.nextInt(5);
if(a == 1)
{
word=("Peace");
}
if(a == 2)
{
word=("Nuts");
}
if(a == 3)
{
word=("Cool");
}
if(a == 4)
{
word=("Fizz");
}
if(a == 5)
{
word=("Awesome");
}
return (word);
}
}
Ok, so this is my code for a hangman game, the only thing I have left to do is to get my program to randomize one of the words, which it should do in the method successfully. But the only problem I'm having is getting the String variable "word" to go back to the main class (there are errors underlining all the "word" variables in the main class).
If I could get help with either this or another way to produce a random word from a list, that would be amazing.
In java, parameters are passed by value and not by reference. Therefore, you cannot change the reference of a parameter.
In your case, you need to do:
public static String getRandomWord() {
switch(new Random().nextInt(5)) {
case 0:
return "Peace";
case 1:
return "Nuts";
// ...
default:
throw new IllegalStateException("Something went wrong!");
}
}
And in main:
// ...
String word = getRandomWord();
int len = word.length();
// ...
You can't modify the caller's reference.
RandomWord(word);
needs to be something like
word = RandomWord(word);
Also, by convention, Java methods start with a lower case letter. And, you could return the word without passing one in as an argument and I suggest you save your Random reference and use an array like
private static Random rand = new Random();
public static String randomWord() {
String[] words = { "Peace", "Nuts", "Cool", "Fizz", "Awesome" };
return words[rand.nextInt(words.length)];
}
And then call it like
word = randomWord();

why is indexof not working?

I have a program for a hangman game and the indexof is not working for me? its on line 30. I have been trying to figure it out but I cannot.if (guessedWord.indexOf(letter) >= 0). I will keep trying to find out what I did wrong
import java.io.PrintStream;
import java.util.Scanner;
public class Hangman
{
public static void main(String[] args)
{
String[] words = { "write", "program", "that", "receive", "positive" };
Scanner input = new Scanner(System.in);
char anotherGame;
do
{
int index = (int)(Math.random() * words.length);
String hiddenWord = words[index];
StringBuilder guessedWord = new StringBuilder();
for (int i = 0; i < hiddenWord.length(); i++) {
guessedWord.append('*');
}
int numberOfCorrectLettersGuessed = 0; int numberOfMisses = 0;
while (numberOfCorrectLettersGuessed < hiddenWord.length()) {
System.out.print("(Guess) Enter a letter in word " + guessedWord +
" > ");
String s = input.nextLine();
char letter = s.charAt(0);
if (guessedWord.indexOf(letter) >= 0) {
System.out.println("\t" + letter + " is already in the word");
} else if (hiddenWord.indexOf(letter) < 0) {
System.out.println("\t" + letter + " is not in the word");
numberOfMisses++;
} else {
int k = hiddenWord.indexOf(letter);
while (k >= 0) {
guessedWord.setCharAt(k, letter);
numberOfCorrectLettersGuessed++;
k = hiddenWord.indexOf(letter, k + 1);
}
}
}
System.out.println("The word is " + hiddenWord + ". You missed " + numberOfMisses + (numberOfMisses <= 1 ? " time" : " times"));
System.out.print("Do you want to guess for another word? Enter y or n> ");
anotherGame = input.nextLine().charAt(0);
}while (anotherGame == 'y');
}
}
You are passing in a char where String is expected. Try using String.valueOf(letter) like this:
if (guessedWord.indexOf(String.valueOf(letter)) >= 0) {
// Your code
}
StringBuilder#indexOf(char) is undefined. You could do
if (guessedWord.indexOf(Character.toString(letter)) >= 0) {
there's no indexOf(char) method for a StringBuilder.
guessedWord.indexOf(letter)
should be
if (guessedWord.toString().indexOf(letter) >= 0) {

Java - Unhandled exception error when using "continue" in a for loop?

This is a program that stores 10 unique strings. If the user enters a string that already exists in the array, the user will get an error. My code is working perfectly for the first string that I enter, but throws an exception after that and I don't know why. How do I fix this and make it work?
P.S. I don't want to use a Set. I want to do it with an array.
Edit: Error name: Exception in thread "main" java.lang.NullPointerException
Java Result: 1
Thanks.
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int stringNumber = 0;
String[] stringArray = new String[10];
for (int i = 0; i <= stringArray.length; i++) {
boolean itemExists = false;
out.println("\nEnter a string");
String input = keyboard.next();
if (i > 0) {
for (int j = 0; j < stringArray.length; j++) {
if (stringArray[j].equalsIgnoreCase(input)) {
itemExists = true;
out.println("Item \"" + input + "\" already exists.");
break;
} else {
continue; // Unhandled exception error. If I don't have "continue" here, the program doesn't work properly after the first number.
}
}
}
if (itemExists == false) {
stringArray[stringNumber] = input;
out.println("\"" + stringArray[stringNumber] + "\"" + " has been stored.");
} else {
out.println("Try again.");
}
PrintArray(stringArray);
stringNumber++;
}
}
public static void PrintArray(String[] stringArray) {
for (int i = 0; i <= 9; i++) {
if (stringArray[i] == null) {
out.print(" ");
} else {
out.print("\nYour strings:");
out.print(" " +stringArray[i] + " ");
}
}
}
you problem is this if (stringArray[j].equalsIgnoreCase(input)) {, you refern to null element as you array do not contain nothing.
You can solve this
if (input.equalsIgnoreCase(stringArray[j])) {
Now you compare the value agains the array items that may be null.
Check the example code
private final static Scanner keyboard = new Scanner(System.in);
private final static String[] stringArray = new String[10];
public static void main(String[] args) {
int stringNumber = 0;
for (int i = 0; i < stringArray.length; i++) {
System.out.println("\nEnter a string");
String input = readNextItem();
if(isInputExist(input)) {
System.out.println("Item \"" + input + "\" already exists.");
System.out.println("Try again.");
} else {
stringArray[stringNumber++] = input;
System.out.println("\"" + input + "\"" + " has been stored.");
}
printArray(stringArray);
}
}
private static String readNextItem() {
return keyboard.next();
}
private static boolean isInputExist(String input) {
for(String stored : stringArray) {
if(input.equalsIgnoreCase(stored)) {
return true;
}
}
return false;
}
You're getting the NullPointerException because you're accessing an empty array. In the second loop you're looping over the entire stringArray array but you've inserted the first i elements.
Change this:
for (int j = 0; j < stringArray.length; j++) {
with this:
for (int j = 0; j < i; j++) {
P.s.
I suggest you to use a Set instead of the array.
Here a version with Set:
int numStrings = 10;
Set<String> inserted = new HashSet<String>();
while(inserted.size()<=numStrings) {
out.println("\nEnter a string");
String input = keyboard.next();
if (inserted.contains(input)) {
out.println("Item \"" + input + "\" already exists.");
out.println("Try again.");
} else {
inserted.add(input);
out.println("\"" + input + "\"" + " has been stored.");
}
}
out.println(inserted);
The problem is this inner loop:
for (int j = 0; j < stringArray.length; j++) {
if (stringArray[j].equalsIgnoreCase(input)) {
itemExists = true;
out.println("Item \"" + input + "\" already exists.");
break;
} else {
continue; // Unhandled exception error. If I don't have "continue" here, the program doesn't work properly after the first number.
}
}
Its not the continue statement that causes the problem, its that you invoke
stringArray[j].equalsIgnoreCase(input)
in the if - stringArray[j] isn't yet filled with a String, it will cause the NullPointerException. You can just reverse the expression:
input.equalsIgnoreCase(stringArray[j])
(That is assuming "input" is never NULL)

Categories