What should I do to fix this scanner-related bug? - java

Even though this code compiles:
import java.util.Scanner; // imports the Scanner class from the java.util package
public class ScannerPractice {
public static void main(String args[]) {
Scanner word = new Scanner("word 1 2 3 4"); // creates a new Scanner objecrt with a string as its input
String scaStr = word.nextLine(); // converts scanner to string
String strArr[] = new String[10];
// as long as the scanner has another character...
for (int i = 0; i < scaStr.length(); i++) {
int j = 0;
String k = "";
// if the next token is an integer...
if (word.hasNextInt()) {
j = word.nextInt();
k = String.valueOf(j);
strArr[i] = k;
}
// otherwise, skip over that token
else {
word.next();
}
}
String k = "";
// for each character in charArr
for (int i = 0; i < strArr.length; i++) {
// Accumulate each element of charArr to k
k += " " + strArr[i];
}
System.out.print(k);
}
}
I get this error:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at ScannerPractice.main(ScannerPractice.java:28)
The exception refers to line 28, which is:
word.next();
I have tried looking at my for loop that assigns values to the string array, but I still couldn't find the error.
I am racking my brain trying to solve this. Even a hint would be most appreciated.

You already consumed all the strings in your Scanner on this line.
String scaStr = word.nextLine();
So, the scanner doesn't have more characteres and that's why you are getting that error.
I think you don't need to 'convert your scanner to string' in order to iterate over it. You can simply use a while to check if your Scanner has remaining characteres.
while(word.hasNext()) {
int j = 0;
String k = "";
// if the next token is an integer...
if (word.hasNextInt()) {
j = word.nextInt();
k = String.valueOf(j);
strArr[i] = k;
}
// otherwise, skip over that token
else {
word.next();
}
}

Change the loop to check whether the scanner has any more input:
Scanner word = new Scanner("word 1 2 3 4");
String strArr[] = new String[10];
int i = 0;
while (word.hasNext()) {
int j = 0;
String k = "";
if (word.hasNextInt()) {
j = word.nextInt();
k = String.valueOf(j);
strArr[i] = k;
}
else {
word.next();
}
}
It doesn't make sense to iterate over the string you already consumed from the scanner, because then you lose the ability to match tokens. If you wanted to use a string tokenizer you could do that, but then you can drop using the scanner.

If you want your code to run correctly change the input to:
Scanner word = new Scanner("word"+"\n"+"1"+"\n"+"2"+"\n"+"3"+"\n"+"4");
adding newline character solves the problem.

Related

Reversing strings in Java (loops) until "done"

this is a lab for class I'm trying to do. Here's the instructions:
Write a program that takes in a line of text as input, and outputs that line of text in reverse. The program repeats, ending when the user enters "Done", "done", or "d" for the line of text.
Ex: If the input is:
"Hello there
Hey
done"
the output is:
"ereht olleH
yeH"
And here's what I have right now:
public class LabProgram {
public static void main(String[] args) {
/* Type your code here. */
Scanner scnr = new Scanner(System.in);
String[] inputs = new String[100];
String input;
int i = 0;
while (true) {
input = scnr.nextLine();
if(input.equals("Done") || input.equals("done") || input.equals("d"))
break;
inputs[i] = input;
i++;
}
for (int j = 0; j < i; j++) {
int length = inputs[j].length();
String reverse = "";
for (int k = length - i; k >= 0; k--) {
reverse = reverse + inputs[j].charAt(k);
}
System.out.print("\n" + reverse);
}
}
}
Current output
What am I doing wrong??
Iterate through the array, and reverse elements at every index.
This solution is time consuming but does your job
for (int j = 0; j < inputs.lenght; j++) {
int length = inputs[j].length();
char a;
String rev = "";
for(int i =0; i< length; i++){
a = inputs[j].charAt(i);
rev = a + rev;
}
System.out.println(rev);
}
*Try to use StringBuilder And use method reverse -- #Artur Todeschini
To add to what Artur said, an ArrayList of StringBuilders could do the trick quite well:
for(StringBuilder nextEntry : stringBuilderList)
{
nextEntry.reverse();
}
The enhanced for-loop will go through each entry in the ArrayList, and the StringBuilder's reverse will change the order of the letters.
EDIT TO SHOW FORMATTING
ArrayList<StringBuilder> stringBuilderList= new ArrayList<>();
*note. given that this is for a lab, its probably for learning purposes and using built-in classes that does all the work for you are usually not the intended solution. -- #experiment unit 1998X
Try to use StringBuilder
And use method reverse
This is another "ArrayList and StringBuilder-less" version.
Create two Strings, one filled and one empty:
String nextString = stringArray[i],
template = new String();
Loop through the length of the String, adding the next character in from the end each time through.
int length = nextString.length() - 1;
for(int j = 0; j < length; j++)
{
template += nextString.charAt(length - j);
}
Add the whole String to the String array's index
stringArray[i] = template;
NOTE
This is an inner loop for a String array and is NOT complete code

Alternative way to get the string input from the user [duplicate]

This question already has answers here:
Why does input.nextint method have a \n as a leftover?
(2 answers)
What does java.lang.ArrayIndexOutOfBoundsException mean? [duplicate]
(7 answers)
Closed 2 years ago.
I have implemented the following code which takes these values as input:-
3 6
CLICK 1
CLICK 2
CLICK 3
CLICK 2
CLOSEALL
CLICK 1
But for taking string input I tried nextLine() but it is not taking input in that case.If I use next() then it treats CLICK and 1 as two different strings and so I am getting ArrayIndexOutOfBoundsException as I am splitting the string and parsing it to int. What is the alternative to handling such inputs?
import java.util.*;
public class TweetClose {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int open = 0;
int a[] = new int[50];
for (int i = 1; i <= n; i++) {
a[i] = 0;
}
for (int i = 0; i < k; i++) {
String s = sc.nextLine();
if (s.equals("CLOSEALL")) {
open = 0;
for (int j = 1; j <= n; j++) {
a[j] = 0;
}
} else {
String[] st = s.split(" ");
int y = Integer.parseInt(st[1]);
if (a[y] != 1) {
a[y] = 1;
open++;
}
}
System.out.println(open);
}
sc.close();
}
}
sc.nextInt() does not scan the carriage return symbol. You need to make sure to scan that before trying to parse the next input.
e.g.:
import java.util.*;
public class TweetClose {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
int k = sc.nextInt();
sc.nextLine();
int open = 0;
int[] a = new int[50];
for (int i = 1; i <= n; i++) {
a[i] = 0;
}
for (int i = 0; i < k; i++) {
String s = sc.nextLine();
if (s.equals("CLOSEALL")) {
open = 0;
for (int j = 1; j <= n; j++) {
a[j] = 0;
}
} else {
String[] st = s.split(" ");
int y = Integer.parseInt(st[1]);
if (a[y] != 1) {
a[y] = 1;
open++;
}
}
System.out.println(open);
}
sc.close();
}
}
The problem caused by using nextLine(). You should use next() instead because you want to process the next token.
After processing all tokens, the final line-break of the current line is still in memory. nextLine() returns that line break "\n". Then you process it:
String[] st = s.split(" ");
int y = Integer.parseInt(st[1]);
The split function returns an array with only one element (the "\n"), therefore you cannot parse st[1]. There is no such element, only st[0] exists.
It will work with next() instead of nextLine() because next() skips over the line break and proceeds with the next token of the next line.
This is a very common mistake because there is no nextString() function.

Create array with reversed words from user string

I am creating a program in which a user enters a string of words (Ex: I love you), and the program returns an array of the words in the string spelled backwards (Ex: I evol ouy). However, I cannot get my code to properly compile, and tried debugging, but cannot see where the problem is.
I tried to look for similar problems here on Slack, but the problems are found were concerned with rearranging words from a string, (ex: you I love), and I cannot find a problem similar to mine, involving turning string into an Array and then manipulating the array.
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string to see it in reverse: ");
String userEntry = sc.nextLine();
char[] entryToChar = userEntry.toCharArray();
System.out.println(Arrays.toString(entryToChar));
String[] splitInput = userEntry.split(" ");
String reverseWord = "";
int temp;
String[] reverseString = new String[splitInput.length];
for (int i = 0; i < splitInput.length; i++)
{
String word = splitInput[i];
for (int j = word.length()-1; j >= 0; j--)
{
reverseWord = reverseWord + word.charAt(j);
}
for (int k = 0; k < splitInput.length; k++) {
temp = splitInput[i];
splitInput[i] = reverseWord[j];
reverseWord[j] = temp;
}
} System.out.println("Your sttring with words spelled backwards is " + reverseWord[j]);
I am avoiding using the 'StringBuilder' method as I have not yet studied it, and trying to see if I can get the new string using swapping, as in the code below:
temp = splitInput[i];
splitInput[i] = reverseWord[j];
reverseWord[j] = temp;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String word, reverseWord;
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string to see it in reverse: ");
String userEntry = sc.nextLine();
userEntry: I love you
String[] splitInput = userEntry.split(" ");
splitInput: [I, love, you]
for (int i = 0; i < splitInput.length; i++)
{
word = splitInput[i];
reverseWord = "";
for (int j = word.length()-1; j >= 0; j--)
{
reverseWord = reverseWord + word.charAt(j);
}
splitInput[i] = reverseWord;
}
splitInput: [I, evol, uoy]
System.out.println("Your string with words spelled backwards is: " + String.join(" ", splitInput));
}
}
Your string with words spelled backwards is: I evol uoy
Your code is not getting compiled because tmp variable is declared as int while splitInput[i] is String.
The other problem is variable j is outside its block scope from where you are trying to access.
Make your logic clear before writing code to achieve correct result.
A good Java programmer should know which tools exist in the language and make use of them in her/his design appropriately. I would suggest to use the class StringBuilder, which has a method for reversing the string. Your program could look like this:
while in.hasNext() {
StringBuilder sb = in.next();
sb.reverse();
System.out.println(sb.toString());
}
If you want to write the reverse function yourself for practice then you can simply define a method that takes a string and returns a reversed string and call that method in place of sb.reverse().
Please know that String in Java is an immutable object. You cannot modify it directly. You can have modified copies returned.
StringBuilder on the other hand allows the programmer to modify the object directly as you can see in the code above.
You need to split original string into an array and then reverse each one and insert into the new array, here you can use StringBuilder as good practice.
class Testarray{
public static void main(String args[]){
String str = "I am Engineer";
String[] spArray = str.split(" ");
String farr[] = new String[spArray.length];
for(int i=0;i<spArray.length;i++){
String split = spArray[i];
farr[i]=reverseString(split);
}
for(int i=0;i<farr.length;i++){
System.out.println(farr[i]);
}
}
public static String reverseString(String str){
char ch[]=str.toCharArray();
String rev="";
for(int i=ch.length-1;i>=0;i--){
rev+=ch[i];
}
return rev;
}
}
There are a few things going on here, and I think in some places you're mixing up between strings and arrays.
Let's try to break this problem down into smaller problems.
First, we need to reverse a single word. Your first inner loop (the one that uses j) does that, so let's extract it into its own method:
public static String reverseWord(String word) {
String reverseWord = "";
for (int j = word.length()-1; j >= 0; j--) {
reverseWord = reverseWord + word.charAt(j);
}
return reverseWord;
}
Although, you should note that concatenating strings like that in a loop isn't great for performance, and using a StringBuilder would probably be faster (although with such a small application, it probably won't be noticeable):
public static String reverseWord(String word) {
StringBuilder reverseWord = new StringBuilder(word.length());
for (int j = word.length()-1; j >= 0; j--) {
reverseWord = reverseWord.append(word.charAt(j));
}
return reverseWord.toString();
}
Once you have that, you can split the input string (like you did), revere each word, and join them back together:
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string to see it in reverse: ");
String userEntry = sc.nextLine();
String[] splitInput = userEntry.split(" ");
for (int i = 0; i < splitInput.length; i++) {
splitInput[i] = reverseWord(splitInput[i]);
}
System.out.println("Your sttring with words spelled backwards is " +
String.join(" ", splitInput));
All you need is to split your original sentence into separate words and use StringBuilder.reverse() to get words in reverse:
public static void main(String... args) {
String str = getSentenceFromConsole();
System.out.println("Your string with words spelled backwards is '" + reversLettersInWords(str) + '\'');
}
private static String getSentenceFromConsole() {
try (Scanner scan = new Scanner(System.in)) {
System.out.print("Enter a string to see it in reverse: ");
return scan.nextLine();
}
}
private static String reversLettersInWords(String str) {
return Arrays.stream(str.split("\\s+"))
.map(word -> new StringBuilder(word).reverse().toString())
.collect(Collectors.joining(" "));
}
i try with your code
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string to see it in reverse: ");
String userEntry = sc.nextLine();
String[] splitInput = userEntry.split(" ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < splitInput.length; i++) {
String word = splitInput[i];
for (int j = word.length() - 1; j >= 0; j--) {
sb.append(word.charAt(j));
}
sb.append(" ");
}
System.out.println("Your sttring with words spelled backwards is " + sb.toString());
here i remove all access line of code....
String input = "i love you";
StringBuilder input1 = new StringBuilder();
input1.append(input);
input1 = input1.reverse();
System.out.println(input1);
You can use this implementation to try to reverse the string elements in the array.

Why Exception in thread "main" java.util.NoSuchElementException?

import java.io.*;
import java.util.*;
public class chopMiddle {
public static void main(String[] args) {
String sample = "1,2,3,4,5";
StringTokenizer tokenizer = new StringTokenizer(sample, ",");
while(tokenizer.hasMoreTokens()) {
int convertedToInt = Integer.parseInt(tokenizer.nextToken());
int [] array = new int [3];
for(int i = 0; i < array.length; i++)
{
array[i] = Integer.parseInt(tokenizer.nextToken());
System.out.println(array[i] + " ");
}
}
}
}
I try to break the string into tokens and uses Integer.parseInt method to convert the tokens into int value.
I want to return an array of size 3 which contains the int values of the 2nd to the 4th integers from the string to the caller. Am i doing something wrong, because it shows below message when i compiled
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at chopMiddle.main(chopMiddle.java:18)
The problem will be when it gets to the 5th token, it will read it, then create a new array and try to read 3 more.
After you have read the 2nd, 3rd and 4th, you should break both loops.
while(tokenizer.hasMoreTokens()) {
int convertedToInt = Integer.parseInt(tokenizer.nextToken());
int [] array = new int [3];
for(int i = 0; i < array.length && tokenizer.hasMoreTokens(); i++) //check hasMoreTokens
{
array[i] = Integer.parseInt(tokenizer.nextToken());
System.out.println(array[i] + " ");
}
}
you need to check every time when you call: tokenizer.nextToken()
If you check if tokenizer has more elements in the for loop itself then you won't require while loop at all.
try below example :
public static void main(String[] args) {
String sample = "1,2,3,4,5";
StringTokenizer tokenizer = new StringTokenizer(sample, ",");
int[] array = new int[3];
for (int i = 0; i < array.length && tokenizer.hasMoreTokens(); i++) {
array[i] = Integer.parseInt(tokenizer.nextToken());
System.out.println(array[i] + " ");
}
}

Changing input so in can take any length of string, problems with output

Currently I have a method that asks user for an input string but only outputs the first 16 characters! The method is supposed to take in any length of string then output the characters in 4x4 blocks after it does the following: first row remains the same. Shift the second row one position to the left, then shifts the third row two positions to the left. Finally, shift the fourth row three positions to the left. As of now it will only output the first 4x4 block
Also I am not sure how I can change the method so it doesnt ask for user input
I would like it to use a given string like:
String text = shiftRows("WVOGJTXQHUHXICWYYMGHTRKQHQPWKYVGLPYSPWGOINTOFOPMO");
"WVOGJTXQHUHXICWYYMGHTRKQHQPWKYVGLPYSPWGOINTOFOPMO" is the given encrypted string I would like to use. but without asking for user input..I keep getting errors and incorrect outputs..please show how I might fix this
code I am using:
public class shiftRows {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String[] input= new String[4];
String[] output= new String[4];
System.out.println("Enter a String");
String inputStr = sc.next();
for (int i = 0, n = 0; i < 4; i++, n+=4) {
input[i] = inputStr.substring(0+n, 4+n);
}
// -
output[0] = input[0];
for(int i=1; i<4; i++)
{
output[i] = Shift(input[i],i);
}
for(int i=0; i<4; i++)
{
System.out.println(output[i]);
}
}
public static String Shift(String str, int shiftNum)
{
char[] out = new char[4];
if(shiftNum==1)
{
out[0]=str.charAt(1);
out[1]=str.charAt(2);
out[2]=str.charAt(3);
out[3]=str.charAt(0);
}
if(shiftNum==2)
{
out[0]=str.charAt(2);
out[1]=str.charAt(3);
out[2]=str.charAt(0);
out[3]=str.charAt(1);
}
if(shiftNum==3)
{
out[0]=str.charAt(3);
out[1]=str.charAt(0);
out[2]=str.charAt(1);
out[3]=str.charAt(2);
}
return new String(out);
}
}
Here's a good way to do it :
import java.util.Scanner;
public class shiftRows {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String inputStr = "WVOGJTXQHUHXICWYYMGHTRKQHQPWKYVGLPYSPWGOINTOFOPMO";
for (int i = 0 ; i < inputStr.length() ; i++){
System.out.print(inputStr.charAt(i));
if ((i + 1)%4 == 0) System.out.println();
}
}
}
If you want to stock it into a String, just concatenate at each loop and add a "\n" each time the if test is valid.

Categories

Resources