Splitting an inputted string by comma and space - java

while(scan.hasNext()){
String line = scan.next();
String[] tempArray = line.split(",\\s*");
for (int i=0; i<3; i++){
System.out.println(tempArray[i]);
}
My input file looks like:
A, 0, 3
C, 2, 2
BB, 3, 3
DA, -3, 0
ED, 2, -2
It returns A, then gives me an error. What gives?

I would split on comma and then trim() the String,
while(scan.hasNextLine()){ // <-- hasNextLine()
String line = scan.nextLine(); // <-- nextLine()
String[] tempArray = line.split(","); // <-- split on the comma.
for (int i=0; i<tempArray.length; i++){ // <-- use the array length
System.out.println(tempArray[i].trim()); // <-- trim() the String
}
}

String line = scan.next();
For your input file, the first time you access this, line will be equal to "A,", which is not what you wanted.
This is because Scanner#next() only reads up until a whitespace character, which is present in the input file between A, and 0,. Hence, why only A, is returned.
Instead use
String line = scan.nextLine();
Which will read up until a line break. So the first loop will set line to "A, 0, 3".
Debugging can really help improve programming abilities. Printing out the return of line to see what is being processed could have definitely helped with this. Being able to then figure out what is happening to produce those results is a lot easier.

Related

Using Scanner and Arrays's to add BigInts

This is a project from school, but i'm only asking for help in the logic on one small part of it. I got most of it figured out.
I'm being given a file with lines of string integers, for example:
1234 123
12 153 23
1234
I am to read each line, compute the sum, and then go to the next one to produce this:
1357
188
1234
I'm stuck on the scanner part.
public static void doTheThing(Scanner input) {
int[] result = new int[MAX_DIGITS];
while(input.hasNextLine()) {
String line = input.nextLine();
Scanner linesc = new Scanner(line);
while(linesc.hasNext()) {
String currentLine = linesc.next();
int[] currentArray = convertArray(stringToArray(currentLine));
result = addInt(result, currentArray);
}
result = new int[MAX_DIGITS];
}
}
In a nutshell, I want to grab each big integer, put it an array of numbers, add them, and then i'll do the rest later.
What this is doing it's basically reading all the lines and adding everything and putting it into a single array.
What i'm stuck on is how do I read each line, add, reset the value to 0, and then read the next line? I've been at this for hours and i'm mind stumped.
Edit 01: I realize now that I should be using another scanner to read each line, but now i'm getting an error that looks like an infinite loop?
Edit 02: Ok, so after more hints and advice, I'm past that error, but now it's doing exactly what the original problem is.
Final Edit: Heh....fixed it. I was forgetting to reset the value to "0" before printing each value. So it makes sense that it was adding all of the values.
Yay....coding is fun....
hasNext method of the Scanner class can be used to check if there is any data available in stream or not. Accordingly, next method used to retrieve next continuous sequence of characters without white space characters. Here use of the hasNext method as condition of if doesn't make any sense as what you want is to check if the there are any numerical data left in the current line. You can use next(String pattern).
In addition, you can try this solution even though it is not optimal solution...
// In a loop
String line = input.nextLine(); //return entire line & descard newline character.
String naw[] = line.split(" "); //split line into sub strings.
/*naw contains numbers of the current line in form of string array.
Now you can perfom your logic after converting string to int.*/
I would also like to mention that it can easily & efficiently be done using java-8 streams.
An easier approach would be to abandon the Scanner altogether, let java.nio.io.Files to the reading for you and then just handle each line:
Files.lines(Paths.get("/path/to/my/file.txt"))
.map(s -> Arrays.stream(s.split("\\s+")).mapToInt(Integer::parseInt).sum())
.forEach(System.out::println);
If i were you i would be using the BufferedReader insted of the Scanner like this:
BufferedReader br = new BufferedReader(new FileReader("path"));
String line = "";
while((line = br.readLine()) != null)
{
int sum = 0;
String[] arr = line.split(" ");
for(String num : arr)
{
sum += Integer.parseInt(num);
}
System.out.println(sum);
}
Considering the level you're on, I think you should consider this solution. By using only the scanner, you can split the lines into an array of tokens, then iterate and sum the tokens by parsing them and validating that they're not empty.
import java.util.*;
class SumLines {
public static void main(String[] args) {
Scanner S = new Scanner(System.in);
while(S.hasNext()) {
String[] tokens = S.nextLine().split(" ");
int sum = 0;
for(int i = 0; i < tokens.length; i++) {
if(!tokens[i].equals("")) sum += Integer.parseInt(tokens[i]);
}
System.out.println(sum);
}
}
}

Is there a way around not advancing a line with Scanner (Java)

Okay so I'm having a slight problem with scanner advancing an extra line. I have a file that has many lines containing integers each separated by one space. Somewhere in the file there is a line with no integers and just the word "done".
When done is found we exit the loop and print out the largest prime integer that is less than each given integer in each line(if integer is already prime do nothing to it). We do this all the way up until the line with "done".
My problem: lets say the file contains 6 lines and on the 6th line is the word done. My output would skip lines 1, 3 and 5. It would only return the correct values for line 2 and 4.
Here's a snippet of code where I read the values in:
Scanner in = new Scanner(
new InputStreamReader(socket.getInputStream()));
PrintStream out = new PrintStream(socket.getOutputStream());
while(in.nextLine() != "done"){
String[] arr = in.nextLine().split(" ");
Now I sense the problem is that the nextLine call in my loop advances the line and then the nextline.split call also advances the line. Thus, all odd number lines will be lost. Would there be another way to check for "done" without advancing a line or is there a possible command I could call to somehow reset the scanner back to the start of the loop?
The problem is you have 2 calls to nextLine() try something like this
String line = in.nextLine();
while (!"done".equals(line)) {
String[] arr = line.split(" ");
// Process the line
if (!in.hasNextLine()) {
// Error reached end of file without finding done
}
line = in.nextLine();
}
Also note I fixed the check for "done" you should be using equals().
I think you are looking for this
while(in.hasNextLine()){
String str = in.nextLine();
if(str.trim().equals("done"){
break;
}else{
String[] arr = str.split("\\s+");
//then do whatever you want to do
}
}

Array adds 0 as the first element instead of my input [java]

I've been writing this program to count the vowels in string/a line of strings. Now, I've got the whole program worked out and it does correctly output the number of vowels for all inputs, but the problem is that the first input of the array is always 0 / nonexistant for some reason.
I'll give you an example and the code here, it's kind of hard to explain:
Scanner sc = new Scanner(System.in);
int numberOfEntries = sc.nextInt() //this would be the number of lines of strings
String[] array = new String[numberOfEntries];
int k = 0;
while(sc.hasNext() && k < numberOfEntries){
array[k] = sc.nextLine();
k++;
}
So this is the part of the code that is relevant to the problem, the rest of it is fine. For some reason, when I input the following lines:
5
abcd
efgh
ijkl
mnop
qrst
The output I will get if I outprint the array is this:
[, abcd, efgh, ijkl, mnop]
I've tried using just the
for(int i = 0; i < array.length; i++){
array[i] = sc.nextLine();
}
thinking that it might solve the issue but nothing changed. I am out of ideas now, though I am sure I just made some silly little error somewhere and I just don't see it.
Kind regards, George
You get the empty line because of the '\n' that sits in the buffer after you call nextInt(). You press Enter after typing in your integer. Scanner consumes the integer in the call of nextInt(), but it does not touch '\n' that follows.
To fix this problem, call nextLine after reading your int, and discard the result:
int numberOfEntries = sc.nextInt();
sc.nextLine(); // Throw away the '\n' after the int
The statement int numberOfEntries = sc.nextInt(); reads the number, leaving the next character (a newline) as the next character to be read.
The first call to sc.nextLine() see this newline and recognizes it as the end on an (empty) line. For your sample input, this causes the call to return an empty string.
The solution is to add an extra call to sc.nextLine() after the sc.nextInt() to consume (and then discard) any characters after the last digit up to the end of the line.
(Actually ... this is a fairly common beginner's mistake with the Scanner API.)
Thats because the Scanner.nextInt() method does not read the last newline character of your input, and thus that newline is consumed in the next call to Scanner.nextLine().

Java Array Index Out of Bound

I have the following code that reads through a line of students and the program should split at each white space then go to the next part of the text but I get arrayindexoutofBound exception.
The text file has several lines like this:
130002 Bob B2123 35 34 B2132 34 54 B2143 23 34
public static void main(String[] args) throws FileNotFoundException {
File f = new File("C:\\Users\\Softey\\Documents\\scores.txt");
Scanner sc = new Scanner(f);
List<MarkProcessing> people = new ArrayList<MarkProcessing>();
while(sc.hasNextLine()){
String line = sc.nextLine();
String[] details = line.split("\\s+");
String regNumber = details[0];
String name = details[1];
String modOne= details[2];
int courseM = Integer.parseInt(details[3]);
int examM = Integer.parseInt(details[4]);
String modTwo = details[5];
int courseM2 = Integer.parseInt(details[6]);
int examM2 = Integer.parseInt(details[7]);
String modThree = details[8];
int courseM3 = Integer.parseInt(details[9]);
int examM3= Integer.parseInt(details[10]);
MarkProcessing p = new MarkProcessing(regNumber, name, modOne,courseM, examM, modTwo,courseM2,examM2, modThree, courseM3, examM3);
people.add(p);
}
}
}
When it goes to details[1] I get the index error.
Without information regarding the input file, I am going to guess this is because of blank lines in your file. If this is the case, you should try something to ensure that you have enough pieces.. For this, your while loop could be something like this.
while(sc.hasNextLine()){
String line = sc.nextLine();
String[] details = line.split("\\s+");
if(details.length < 11) continue; // skip this iteration
...
}
Keep in mind this is only going to work if you are checking at least 11 items per line. If you need a more advanced method of parsing the input, whereas they may have any number of courses. You are better off thinking of another approach than simply storing values directly from indices.
You should try printing the line before parsing it so that you can see what causes it to blow up.
String line = sc.nextLine();
String[] details = line.split("\\s+");
String regNumber = details[0];
String name = details[1];
String modOne= details[2];
You are splitting on chunks of spaces. In the event you encounter a line with no spaces, then there will only be a single element and therefore details[1] will throw an IndexOutOfBoundsException.
My suggestion is to examine your input carefully. Does it have at trailing line feed? If so, that may be interpreted as a blank line
130002 Bob B2123 35 34 B2132 34 54 B2143 23 34
<blank line>
To split by space, you need to use:
String[] details = line.split(" "); // "\\s+" -> does not split by space.
In your case, it is trying to split the line by the regex pattern '//s+' and since this is not found, it considers the whole line to be one string. In this case, the size of the string array is 1. There is no details[1] and hence you get this error.

Splitting string into array of strings causing NumberFormatException

I am having an extremely difficult time splitting each line from the text file into an array of strings and using it like I need to. The split() seems to work okay. I end up having an array of strings, where the first slot of the strings array contains a number that I need to parse as an int, to continue my code. For some reason, I keep getting the error shown below that I can't seem to figure out.
My goal is it to simply store every line of the text file that contains letters, in an array, and parse the number which is going to be the first value of the line, as an integer. Once I accomplish this, I need to be able to use every preceding group of letters independently, so I am trying to get those in an array as well.
I appreciate any help with this.
Many thanks in advance!
NOTE: numGrammars is the first number shown on the first line of the text file.
My Code
numGrammars = Integer.parseInt(fin.next());
System.out.println("Num Grammars:" + numGrammars);
for(int v=0; v < numGrammars; v++){
int numVariables = Integer.parseInt(fin.next());
System.out.printf("numVariables: %s", numVariables);
for(int z=0; z < numVariables; z++){
//reads in variable line
String line = fin.nextLine();
String[] strings = line.split(" ");
for(int m=0; m < strings.length; m++){
int numRules = Integer.parseInt(strings[0]);
//All other array slots in strings array should be groups of letters on group per slot...
}
}
}
Console Output
Num Grammars:2
numVariables: 3Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Methods.readFile(Methods.java:34)
at Main.main(Main.java:12)
Text file I am reading from:
1
3
2 S AB BB
3 A BB a b
2 B b c
Only use fin.nextLine(). After the call to next(), the cursor is right after the numVariables value 3, but before the newline. When you call nextLine() after that, it returns everything between the cursor and the newline, which is an empty string! Using nextLine() each time always places the cursor after the newline, and everything is OK.
numGrammars = Integer.parseInt(fin.nextLine());
System.out.println("Num Grammars:" + numGrammars);
for(int v=0; v < numGrammars; v++){
int numVariables = Integer.parseInt(fin.nextLine());
System.out.printf("numVariables: %s", numVariables);
for(int z=0; z < numVariables; z++){
//reads in variable line
String line = fin.nextLine();
String[] strings = line.split(" ");
for(int m=0; m < strings.length; m++){
int numRules = Integer.parseInt(strings[0]);
//All other array slots in strings array should be groups of letters on group per slot...
}
}
}
You don't say what fin is, so I can't say what it does for next() versus nextLine(), but perhaps you are picking up the newline character in your string.

Categories

Resources