Scanner system.in, doesnt read the 1st,3rd,5th,etc input [duplicate] - java

This question already has answers here:
Scanner skipping every second line from file [duplicate]
(5 answers)
Closed 4 years ago.
I have the following code, I am suppose to give the input though system.in, however, the program skit the frist input, but it reads the secod one, it skips the 3rd input but it reads the forth one and so on. I can not figure out the problem.
here is my code:
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;
public class problem1a {
private static HashMap<String,Integer> ales;
private static int counter = 0;
private static ArrayList<String> names;
private static ArrayList<String> city;
private static ArrayList<Integer> count;
public static void main(String[] args) throws FileNotFoundException{
Scanner sc = new Scanner(System.in);
// initialize name,line variables
names = new ArrayList<String>();
ales = new HashMap<String,Integer>();
//store the names of the city and the corresponding student
while(sc.hasNextLine() ){
String s = removeNumbers(sc.nextLine());
Integer c = ales.get(s);
if(c == null){
ales.put(s, 1);
}
else{
ales.put(s, c.intValue() + 1);
}
if(sc.nextLine().equals(""))
break;
System.out.println(ales.toString());
}
}
}
so here is my input and the output:
input: 3456345 Delft Jan
input: 435243 Delft Tim
{Delft Jan=1}
input: 54322 Delft Tim
input: 3453455 Delft Tim
{Delft Tim=1, Delft Jan=1}
input: 3456345 Delft Jan
input: 3456345 Delft Jan
{Delft Tim=1, Delft Jan=2}
can some one please explain to me what is going wrong?
I fixed the problem, the issue was according to the comments that I was using sc.nextLine() twice inside the loop and thats why it would miss the 1st input and read the second one.
the new correct code is this and it works just fine, so thank you guys.
public static void main(String[] args) throws FileNotFoundException{
Scanner sc = new Scanner(System.in);
// initialize name,line variables
names = new ArrayList<String>();
ales = new HashMap<String,Integer>();
//store the names of the city and the corresponding student
while(sc.hasNextLine() ){
String s = removeNumbers(sc.nextLine());
Integer c = ales.get(s);
if(c == null){
ales.put(s, 1);
}
else{
ales.put(s, c.intValue() + 1);
}
if(s.equals(""))
break;
System.out.println(ales.toString());
}
}

That's because you call sc.nextLine() twice inside your loop.
You should call it only once per line:
String nextLine = sc.nextLine();
String s = removeNumbers(nextLine);
...
if("".equals(nextLine)) {
break;
}

while(sc.hasNextLine() ){
String s = removeNumbers(sc.nextLine());
// ...
if(sc.nextLine().equals(""))
break;
}
You're calling sc.nextLine() twice inside the while loop. Assign nextLine() to a variable once, and then replace all the calls inside the loop with the variable. Like so:
while(sc.hasNextLine() ){
String line = sc.nextLine();
String s = removeNumbers(line);
// ...
if(line.equals(""))
break;
}

It does read them. The problem is more like it reads the some inputs in the wrong places!
String s = removeNumbers(sc.nextLine()); //this line reads the 1st, 3rd, 5th... line
if(sc.nextLine().equals("")) //this line reads the 2nd, 4th, 6th... lines
You should assign the read line into a String variable instead and use it to remember which line you read last. In fact, you already do it with s. Have you tried if(s.equals(""))?

Code sc.nextLine() is executed twice in while - loop, that's the root cause for your issue. Take care of this, and make some neccessary chance and go ahead.
while(sc.hasNextLine() ){
String s = removeNumbers(sc.nextLine());
Integer c = ales.get(s);
if(c == null){
ales.put(s, 1);
}
else{
ales.put(s, c.intValue() + 1);
}
if(sc.nextLine().equals(""))
break;
System.out.println(ales.toString());
}

Related

How to limit the number of words when reading a line from standard input?

I am new to Stackoverflow and this is my first time asking a question. I have searched my problem thoroughly, however, could not find an appropriate answer. I am sorry if this has been asked. Thank you in advance.
The question is from Hyperskill.com as follows:
Write a program that reads five words from the standard input and outputs each word in a new line.
First, you need to print all the words from the first line, then from the second (from the left to right).
Sample Input 1:
This Java course
is adaptive
Sample Output 1:
This
Java
course
is
adaptive
My trial to solve it
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
/* I have not initialized the "userInput" String.
* I know that String is immutable in Java and
* if I initialize it to an empty String ""
* and read a String from user.
* It will not overwrite to the "userInput" String.
* But create another String object to give it the value of the user input,
* and references the new String object to "userInput".
* I didn't want to waste memory like that.
*/
String userInput;
String[] userInputSplitFirstLine = new String[3];
String[] userInputSplitSecondLine = new String[2];
Scanner scan = new Scanner(System.in);
userInput = scan.nextLine();
userInputSplitFirstLine = userInput.split("\\s+");
userInput = scan.nextLine();
userInputSplitSecondLine = userInput.split("\\s+");
for(String firstLineSplitted: userInputSplitFirstLine) {
System.out.println(firstLineSplitted);
}
for(String secondLineSplitted: userInputSplitSecondLine) {
System.out.println(secondLineSplitted);
}
scan.close();
}
}
If you try the sample input above, the output will match the sample output above. However, if you write more than 3 words to the first line and/or more than 2 words to the second line, the userInputSplitFirstLine array of size 3 will store more than 3 words. Same goes with the userInputSplitSecondLine array also. My first question is how can an array of size 3 (userInputSplitFirstLine) and an array of size 2 (userInputSplitSecondLine) can hold more than 3 and 2 elements, respectively? My second question is that how can I restrict/limit the number of words that the user can insert in a line; for example, the first line only accepts 3 words and the second line only accepts 2 words?
Also the answer to this question suggested by Hyperskill.com is as follows:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String wordOne = scanner.next();
String wordTwo = scanner.next();
String wordThree = scanner.next();
String wordFour = scanner.next();
String wordFive = scanner.next();
System.out.println(wordOne);
System.out.println(wordTwo);
System.out.println(wordThree);
System.out.println(wordFour);
System.out.println(wordFive);
}
}
You can use next method of scanner object to read string and then it can be printed easily on new line.
while(true){
if(scanner.hasNext()){
System.out.println(scanner.next());
}
else{
break;
}
}
I think this should do the work. Don't hesitate to ask, if you have some questions.
import java.util.Scanner;
class App {
public static void main(String[] args) {
final StringBuffer line = new StringBuffer();
final StringBuffer words = new StringBuffer();
try (final Scanner sc = new Scanner(System.in)) {
while (sc.hasNextLine()) {
final String currentLine = sc.nextLine();
line.append(currentLine).append(System.lineSeparator());
for (final String word : currentLine.split("\\s+")) {
words.append(word).append(System.lineSeparator());
}
}
} finally {
System.out.println(line.toString());
System.out.println();
System.out.println(words.toString());
}
}
}
My first question is how can an array of size 3 (userInputSplitFirstLine) and an array of size 2 (userInputSplitSecondLine) can hold more than 3 and 2 elements, respectively?
The array here:
String[] userInputSplitFirstLine = new String[3];
is not the same one as the one you got from split:
userInputSplitFirstLine = userInput.split("\\s+");
When you do the above assignment, the old array that was in there is basically "overwritten", and now userInputSplitFirstLine refers to this new array that has a length independent of what the old array had. split always return a new array.
My second question is that how can I restrict/limit the number of words that the user can insert in a line; for example, the first line only accepts 3 words and the second line only accepts 2 words?
It really depends on what you mean by "restrict". If you just want to check if there are exactly three words, and if not, exit the program, you can do this:
userInputSplitFirstLine = userInput.split("\\s+");
if (userInputSplitFirstLine.length != 3) {
System.out.println("Please enter exactly 3 words!");
return;
}
You can do something similar with the second line.
If you want the user to be unable to type more than 3 words, then that's impossible, because this is a command line app.
By the way, the code in the suggested solution works because next() returns the next "word" (or what we generally think of as a word, anyway) by default.
hope this will help you!
public class pratice1 {
public static void main (String[]args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
String input1 = sc.nextLine();
char[]a =input.toCharArray();
char[]a1 = input1.toCharArray();
System.out.println(input +""+ input1);
int a2=0;
if(input!=null) {
for(int i=0;i<input.length();i++) {
if(a[i]==' ') {
a2=i;
for(int j=0;j<a2;j++) {
System.out.println(a[i]);
a2=0;
}
}
else System.out.print(a[i]);
}System.out.println("");
for(int i=0;i<input1.length();i++) {
if(a1[i]==' ') {
a2=i;
for(int j=0;j<a2;j++) {
System.out.println(a1[i]);
a2=0;
}
}
else System.out.print(a1[i]);
}
}
}
}
To solve the problem:
Write a program that reads five words from the standard input and
outputs each word in a new line.
This was my solution:
while(scanner.hasNext()){
System.out.println(scanner.next());
}

split method not sperating special characters

I'm working a program that counts the accurrences of words in a text file. The program compiles and runs fine, but I'm tryting to use the split method to seperate special characters such as .,;:!?(){} from the words.
here is an output example
6 eyes,
3 eyes.
2 eyes;
1 eyes?
1 eyrie
As you can see the split fuction is not working. I have tried debugging, but no luck so far. Can anythone point me out to the right direction or tell me what I'm doing wrong. Thank you.
import java.util.*;
import java.io.*;
public class testingForLetters {
public static void main(String[] args) throws FileNotFoundException {
// open the file
Scanner console = new Scanner(System.in);
System.out.print("What is the name of the text file? ");
String fileName = console.nextLine();
Scanner input = new Scanner(new File(fileName));
// count occurrences
Map<String, Integer> wordCounts = new TreeMap<String, Integer>();
while (input.hasNext()) {
input.next().split("[ \n\t\r.,;:!?(){}]" );
String next = input.next().toLowerCase();
if (next.startsWith("a") || next.startsWith("b") || next.startsWith("c") || next.startsWith("d") || next.startsWith("e") ) {
if (!wordCounts.containsKey(next)) {
wordCounts.put(next, 1);
} else {
wordCounts.put(next, wordCounts.get(next) + 1);
}
}
}
// get cutoff and report frequencies
System.out.println("Total words = " + wordCounts.size());
for (String word : wordCounts.keySet()) {
int count = wordCounts.get(word);
System.out.println(count + "\t" + word);
}
}
}
The .split() method returns an array of strings, and right now you aren't setting input.next().split() equal to anything. You have to create an array and set it equal to input.next().split(), and then get the word(s) from the array. You basically need to handle it exactly like you handled the .toLowerCase() part where you set String next = input.next().toLowerCase(). Hope this helps.

java.util.InputMismatchException; null (in java.util.Scanner) [duplicate]

This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 6 years ago.
I have an assignment where I have to read in a file with information about hurricanes from 1980 to 2006. I can not figure out what the error is. I have a section of code like this:
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class Hurricanes2
{
public static void main(String[] args)throws IOException
{
//declare and initialize variables
int arrayLength = 59;
int [] year = new int[arrayLength];
String [] month = new String[arrayLength];
File fileName = new File("hurcdata2.txt");
Scanner inFile = new Scanner(fileName);
//INPUT - read data in from the file
int index = 0;
while (inFile.hasNext()) {
year[index] = inFile.nextInt();
month[index] = inFile.next();
}
inFile.close();
That is just the first part. But in the section with the while statement, there is an error with the year[index] = inFile.nextInt(). I have no idea what the error means and I need help. Thanks in advance.
Try adding index++ as the last line of your while loop. As it is now, you never increment it, so you're only filling and replacing the first numbers in your array.
I personally wouldn't use Scanner() but instead Files.readAllLines(). It might be easier to implement if there is some sort of delimiting character to split the hurricaine data on.
For instance, let's say your text file is this:
1996, August, 1998, September, 1997, October, 2001, April...
You can do the following if these assumptions I've made hold true:
Path path = Paths.get("hurcdata2.txt");
String hurricaineData = Files.readAllLines(path);
int yearIndex = 0;
int monthIndex = 0;
// Splits the string on a delimiter defined as: zero or more whitespace,
// a literal comma, zero or more whitespace
for(String value : hurricaineData.split("\\s*,\\s*"))
{
String integerRegex = "^[1-9]\d*$";
if(value.matches(integerRegex))
{
year[yearIndex++] = value;
}
else
{
month[monthIndex++] = value;
}
}

Correctly scanning a blank input with the Scanner object

I'm working on creating a basic guitar inventory and I'm doing testing with scanner, I was trying to scan a blank entry and when there is a blank entry it should print "ANY" and it does, i'm using scan.useDelimiter("\z"); and now when I enter a correct entry like "fender" it should print "FENDER" but it just prints "ANY" as if the entry was incorrect.. someone know what I can do to solve that problem? Here is an sscce:
import java.util.Scanner;
public class SSCCE {
public static void main(String[] args)
{
System.out.println("Enter a builder name: ");
Scanner scan = new Scanner(System.in);
scan.useDelimiter("\\z"); // count a blank entry (end of input)
String entry_1 = scan.next();
if (entry_1.equalsIgnoreCase("FENDER")
|| entry_1.equalsIgnoreCase("MARTIN")
|| entry_1.equalsIgnoreCase("GIBSON")
|| entry_1.equalsIgnoreCase("COLLINGS")
|| entry_1.equalsIgnoreCase("OLSON")
|| entry_1.equalsIgnoreCase("RYAN")
|| entry_1.equalsIgnoreCase("PRS"))
{
entry_1 = entry_1.toUpperCase();
System.out.println(entry_1);
}
else
{
entry_1 = "ANY";
System.out.println(entry_1);
}
}
}
By default, the scanner removes the delimiter from the tokens it return. When the delimiter was a line break (the default), when you do fender, entry_1 was assigned "fender". After you changed the delimiter, the line break caused by the enter is no longer removed, so you get "fender\n" in entry_1, causing your if condition to fail.
To fix, just do String entry_1 = scan.next().trim(); instead which removes the trailing linebreak.
You can try printing the scanned value to see why it is not going into the if statement.
import java.util.Scanner;
public class SSCCE {
public static void main(String[] args)
{
System.out.println("Enter a builder name: ");
Scanner scan = new Scanner(System.in);
scan.useDelimiter("\\z"); // count a blank entry (end of input)
String entry_1 = scan.next();
System.out.println("Input = [" + entry_1 + "]");
// rest of the code...
}
I think this is due to your use of \\z. Look at this regex tutorial for a more detailed story. For solving your problem, suffice it to say that changing it to \\Z should do the trick. The following code is working for me:
public static final Set<String> names = Sets.newHashSet("martin", "gibson", ...);
public static void main(String[] args) {
System.out.println("Enter a builder name: ");
Scanner scan = new Scanner(System.in);
scan.useDelimiter("\\Z"); // count a blank entry (end of input)
String entry = scan.next();
entry = "any" if (!names.contains(entry.toLowerCase());
System.out.println(entry.toUpperCase());
}
Note: I assumed you are scanning one name at a time. If not, then just use line break.

useDelimiter, read up till first delimiter and then change line

I'm trying to use a Delimiter to pull out the first numbers in a document with 31 rows looking something like "105878-798##176000##JDOE" and put it in an int array.
The numbers I'm interesed in are "105878798", and the number of numbers is not consistent.
I wrote this but can't figure out how to change the line when i reach the first delimiter (of the line).
import java.util.*;
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
int n = 0;
String rad;
File fil = new File("accounts.txt");
int[] accountNr = new int[31];
Scanner sc = new Scanner(fil).useDelimiter("##");
while (sc.hasNextLine()) {
rad = sc.nextLine();
rad.replaceAll("-","");
accountNr[n] = Integer.parseInt(rad);
System.out.println(accountNr[n]);
n++;
System.out.println(rad);
}
}
}
Don't use the scanner for this, use the StringTokenizer and set the delimiter to ##, then just keep calling .nextElement() and you will get the next number no matter how long it is.
StringTokenizer st2 = new StringTokenizer(str, "##");
while (st2.hasMoreElements()) {
log.info(st2.nextElement());
}
(Of course, you can iterate in different ways..)
I would suggest for each line use line.split("[#][#]")[0] (of course haldle your exceptions).
also, rad.replaceAll(...) returns a new String, because String is an imutable object. you should execute parseInt on the returned String and not on rad.
just use the following instead of the equivalent 2 lines in your code:
String newRad = rad.replaceAll("-","");
accountNr[n] = Integer.parseInt(newRad);

Categories