So, I'm using Scanner to parse a text file which is space and newline delimited. Each line has an index number which is loaded into an array and a string which is a label corresponding to that member of the array, like so:
0 Sydney
1 Alice Springs
2 Canberra
3 Bathurst
4 Orange
I'm using the following code to read the file:
public void readIndex (String indexFile)
{
int i = 0;
String label = null;
InputStream input = getClass().getResourceAsStream(indexFile);
Scanner parser = new Scanner(input);
parser.useDelimiter(" ");
while (parser.hasNextLine())
{
i = parser.nextInt();
label = parser.nextLine();
this.setLabel(i, label);
}
}
And finally, this code to print the results:
System.out.println("Cities loaded:");
for (int i = 0; i < cities.vertexCount(); i++)
{
System.out.println(cities.getLabel(i));
}
The strings are showing up fine, but there seems to be a leading whitespace for each of the labels. Here's the output:
Cities loaded:
Sydney
Alice Springs
Canberra
Bathurst
Orange
For example, the first string is being stored as " Sydney".
Is this an issue with my delimiter settings, or have I missed something else really obvious? Thanks in advance!
Scanner#nextInt only consumes integer input so the remaining String will contain a leading whitespace. You need to trim this character
label = parser.nextLine().trim();
Related
I am currently trying to stop printing a line of text after a , character is read on that line a second time from a text file. Example; 14, "Stanley #2 Philips Screwdriver", true, 6.95. Stop reading and print out the text after the , character is read a second time. So the output text should look like 14, "Stanley #2 Philips Screwdriver". I tried to use a limit on the regex to achieve this but, it just omits all the commas and prints out the entire text. This is what my code looks like so far;
public static void fileReader() throws FileNotFoundException {
File file = new File("/Users/14077/Downloads/inventory.txt");
Scanner scan = new Scanner(file);
String test = "4452";
while (scan.hasNext()) {
String line = scan.nextLine();
String[] itemID = line.split(",", 5); //attempt to use a regex limit
if(itemID[0].equals(test)) {
for(String a : itemID)
System.out.println(a);
}//end if
}//end while
}//end fileReader
I also tried to print just part of the text up until the first comma like;
String itemID[] = line.split(",", 5);
System.out.println(itemID[0]);
But no luck, it just prints 14. Please any help will be appreciated.
What about something using String.indexOf and String.substring functions (https://docs.oracle.com/javase/7/docs/api/java/lang/String.html)
int indexSecondOccurence = line.indexOf(",", line.indexOf(",") + 1);
System.out.println(line.substring(0, indexSecondOccurence + 1));
I'd suggest to modify your code as follows.
...
String[] itemID = line.split(",", 3); //attempt to use a regex limit
if(itemID[0].equals(test)) {
System.out.println(String.join (",", itemID[0],itemID[1]));
}
...
The split() call will produce an array with maximum 3 elements. First two will be the string pieces that you need. The last element is the remaining "tail" of the original string.
Now we only need to merge the pieces back with the join() method.
Hope this helps.
I am asking for help on this code that I am making, I want it to replace the last two letters. I am coding a program that will:
Replace four letter words with "FRED"
Replace the last two letters of a word that ends with "ed" to "id"
Finally, replace the first two letters if the word starts with "di" to "id"
I am having difficulty with the second stated rule, I know that for number 3 I can just use replaceFirst() and to use the length for the first rule, but I am not sure how to specifically swap the last two characters in the string.
Here is what I have so far:
package KingFred;
import java.util.Scanner;
public class KingFredofId2 {
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
String king = input.nextLine();
String king22 = new String();
String king23 = new String();
if(king.length()==4)
{
System.out.println("FRED");
}
String myString = king.substring(Math.max(king.length() - 2, 0));
if (myString.equals("ed"))
{
king22 = king.replace("ed", "id");
System.out.println(king22);
}
if(true)
{
king23 = king.replace("di", "id");
System.out.println(king23);
}
}
I am new to Stack Overflow, so please let me know how I can make my questions a little more understandable if this one is not easily comprehended.
Thanks.
There may be a way to more optimally combine the regular expressions, but this will work.
\\b - word boundary (white space, punctuation,etc).
\\b(?:\\w){4}\\b - four letter word
ed\\b - word ending with ed
\\bdi - word starting with di
replaceAll(regex,b) - replace what regex matches with string b
String s =
"Bill charles among hello fool march good deed, dirt, dirty, divine dried freed died";
s = s.replaceAll("\\b(?:\\w){4}\\b", "FRED")
.replaceAll("ed\\b", "id")
.replaceAll("\\bdi", "id");
System.out.println(s);
prints
FRED charles among hello FRED march FRED FRED, FRED, idrty, idvine driid freid F
RED
This is the most simplest way I could think to solve the second case of replacing the last two characters.
import java.util.Scanner;
public class MyClass {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a line or a word: ");
String s = sc.nextLine();
//getting the length of entered string
int length = s.length();
//initializing a new string to hold the last two characters of the entered string
String extract = "";
//checking if length of entered string is more than 2
if (length > 2) {
//extracting the last two letters
extract = s.substring(length - 2);
//updating the original string
s = s.substring(0, length - 2);
}
//checking if the last two characters fulfil the condition for changing them
if (extract.equalsIgnoreCase("ed")) {
//if they do, concatenate "id" to the now updated original string
System.out.println(s + "id");
} else {
//or print the originally entered string
System.out.println(s + extract);
}
}
}
I believe the comments are giving enough explanation and further explanation is not needed.
The problem requires to input different values for each attribute.Ex:
Color Black White
Water Cool Hot Medium
Wind Strong Weak
I made ArrayList of ArrayList of String to store such thing as no. of values of each attribute is not fixed.The user inputs Black White and on hitting new line the program has to start taking values of NEXT attribute( Cool Hot Medium).The no. of attributes has been already specified.I followed some (almost related) answers here and wrote the following code:
ArrayList<ArrayList<String>> attributes = new ArrayList<ArrayList<String>>();
String input;
for(i=0; i<num_of_Attributes ;i++)
{ System.out.print(" Enter attribute no." + i+1 + " : ");
ArrayList<String> list = new ArrayList<String>();
while(! input.equals("\n"))
{
list.add(input);
input = sc.nextLine();
}
attributes.add(list);
}
The program prints "Enter Attribute 1 : " but even after new line it doesn't print "Enter attribute 2 : ".It goes into infinite loop. How can I achieve what the program requires to do? sc is my Scanner object.
You should read:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextLine%28%29
specifically the part that states:
This method returns the rest of the current line, excluding any line separator at the end
So, if the user inputs an empty line with only the line separator \n, you will read an empty line without such line separator.
Check while (!input.isEmpty()) or, even better, while (!input.trim().isEmpty())
As a more general rule, you can debug your program (or even just print input) to try to find out yourself what is the actual value you are checking.
As a quick-Hack you can do sth. like
for (i = 0; i < num_of_Attributes; i++) {
input = " ";
System.out.print(" Enter attribute no." + (i + 1) + " : ");
ArrayList<String> list = new ArrayList<String>();
while (!input.isEmpty()) {
list.add(input);
input = sc.readLine();
}
attributes.add(list);
}
not nice but it works. Please also watch out for calculating in String concaternation. In you code it will print 01, 11, 21 and so on. With brackets it will work.
I have a serious problem with extracting terms from each string line. To be more specific, I have one csv formatted file which is actually not csv format (it saves all terms into line[0] only)
So, here's just example string line among thousands of string lines;
test.csv
line1 : "31451 CID005319044 15939353 C8H14O3S2 beta-lipoic acid C1CS#S[C##H]1CCCCC(=O)O "
line2 : "12232 COD05374044 23439353 C924O3S2 saponin CCCC(=O)O "
line3 : "9048 CTD042032 23241 C3HO4O3S2 Berberine [C##H]1CCCCC(=O)O "
I want to extract "beta-lipoic acid" ,"saponin" and "Berberine" only which is located in 5th position.
You can see there are big spaces between terms, so that's why I said 5th position.
In this case, how can I extract terms located in 5th position for each line?
one more thing ;
the length of whitespace between each six terms is not always equal.
the length could be one,two,three or four..five... something like that..
Another try:
import java.io.File;
import java.util.Scanner;
public class HelloWorld {
// The amount of columns per row, where each column is seperated by an arbitrary number
// of spaces or tabs
final static int COLS = 7;
public static void main(String[] args) {
System.out.println("Tokens:");
try (Scanner scanner = new Scanner(new File("input.txt")).useDelimiter("\\s+")) {
// Counten the current column-id
int n = 0;
String tmp = "";
StringBuilder item = new StringBuilder();
// Operating of a stream
while (scanner.hasNext()) {
tmp = scanner.next();
n += 1;
// If we have reached the fifth column, take its content and append the
// sixth column too, as the name we want consists of space-separated
// expressions. Feel free to customize of your name-layout varies.
if (n % COLS == 5) {
item.setLength(0);
item.append(tmp);
item.append(" ");
item.append(scanner.next());
n += 1;
System.out.println(item.toString()); // Doing some stuff with that
//expression we got
}
}
}
catch(java.io.IOException e){
System.out.println(e.getMessage());
}
}
}
if your line[]'s type is String
String s = line[0];
String[] split = s.split(" ");
return split[4]; //which is the fifth item
For the delimiter, if you want to go more precisely, you can use regular expression.
How is the column separated? For example, if the columns are separated by tab character, I believe you can use the split method. Try using the below:
String[] parts = str.split("\\t");
Your expected result will be in parts[4].
Just use String.split() using a regex for at least 2 whitespace characters:
String foo = "31451 CID005319044 15939353 C8H14O3S2 beta-lipoic acid C1CS#S[C##H]1CCCCC(=O)O";
String[] bar = foo.split("\\s\\s");
bar[4]; // beta-lipoic acid
I am working on a class assignment this morning and I want to try and solve a problem I have noticed in all of my team mates programs so far; the fact that spaces in an int/float/double cause Java to freak out.
To solve this issue I had a very crazy idea but it does work under certain circumstances. However the problem is that is does not always work and I cannot figure out why. Here is my "main" method:
import java.util.Scanner; //needed for scanner class
public class Test2
{
public static void main(String[] args)
{
BugChecking bc = new BugChecking();
String i;
double i2 = 0;
Scanner in = new Scanner(System.in);
System.out.println("Please enter a positive integer");
while (i2 <= 0.0)
{
i = in.nextLine();
i = bc.deleteSpaces(i);
//cast back to float
i2 = Double.parseDouble(i);
if (i2 <= 0.0)
{
System.out.println("Please enter a number greater than 0.");
}
}
in.close();
System.out.println(i2);
}
}
So here is the class, note that I am working with floats but I made it so that it can be used for any type so long as it can be cast to a string:
public class BugChecking
{
BugChecking()
{
}
public String deleteSpaces(String s)
{
//convert string into a char array
char[] cArray = s.toCharArray();
//now use for loop to find and remove spaces
for (i3 = 0; i3 < cArray.length; i3++)
{
if ((Character.isWhitespace(cArray[i3])) && (i3 != cArray.length)) //If current element contains a space remove it via overwrite
{
for (i4 = i3; i4 < cArray.length-1;i4++)
{
//move array elements over by one element
storage1 = cArray[i4+1];
cArray[i4] = storage1;
}
}
}
s = new String(cArray);
return s;
}
int i3; //for iteration
int i4; //for iteration
char storage1; //for storage
}
Now, the goal is to remove spaces from the array in order to fix the problem stated at the beginning of the post and from what I can tell this code should achieve that and it does, but only when the first character of an input is the space.
For example, if I input " 2.0332" the output is "2.0332".
However if I input "2.03 445 " the output is "2.03" and the rest gets lost somewhere.
This second example is what I am trying to figure out how to fix.
EDIT:
David's suggestion below was able to fix the problem. Bypassed sending an int. Send it directly as a string then convert (I always heard this described as casting) to desired variable type. Corrected code put in place above in the Main method.
A little side note, if you plan on using this even though replace is much easier, be sure to add an && check to the if statement in deleteSpaces to make sure that the if statement only executes if you are not on the final array element of cArray. If you pass the last element value via i3 to the next for loop which sets i4 to the value of i3 it will trigger an OutOfBounds error I think since it will only check up to the last element - 1.
If you'd like to get rid of all white spaces inbetween a String use replaceAll(String regex,String replacement) or replace(char oldChar, char newChar):
String sBefore = "2.03 445 ";
String sAfter = sBefore.replaceAll("\\s+", "");//replace white space and tabs
//String sAfter = sBefore.replace(' ', '');//replace white space only
double i = 0;
try {
i = Double.parseDouble(sAfter);//parse to integer
} catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
System.out.println(i);//2.03445
UPDATE:
Looking at your code snippet the problem might be that you read it directly as a float/int/double (thus entering a whitespace stops the nextFloat()) rather read the input as a String using nextLine(), delete the white spaces then attempt to convert it to the appropriate format.
This seems to work fine for me:
public static void main(String[] args) {
//bugChecking bc = new bugChecking();
float i = 0.0f;
String tmp = "";
Scanner in = new Scanner(System.in);
System.out.println("Please enter a positive integer");
while (true) {
tmp = in.nextLine();//read line
tmp = tmp.replaceAll("\\s+", "");//get rid of spaces
if (tmp.isEmpty()) {//wrong input
System.err.println("Please enter a number greater than 0.");
} else {//correct input
try{//attempt to convert sring to float
i = new Float(tmp);
}catch(NumberFormatException nfe) {
System.err.println(nfe.getMessage());
}
System.out.println(i);
break;//got correct input halt loop
}
}
in.close();
}
EDIT:
as a side note please start all class names with a capital letter i.e bugChecking class should be BugChecking the same applies for test2 class it should be Test2
String objects have methods on them that allow you to do this kind of thing. The one you want in particular is String.replace. This pretty much does what you're trying to do for you.
String input = " 2.03 445 ";
input = input.replace(" ", ""); // "2.03445"
You could also use regular expressions to replace more than just spaces. For example, to get rid of everything that isn't a digit or a period:
String input = "123,232 . 03 445 ";
input = input.replaceAll("[^\\d.]", ""); // "123232.03445"
This will replace any non-digit, non-period character so that you're left with only those characters in the input. See the javadocs for Pattern to learn a bit about regular expressions, or search for one of the many tutorials available online.
Edit: One other remark, String.trim will remove all whitespace from the beginning and end of your string to turn " 2.0332" into "2.0332":
String input = " 2.0332 ";
input = input.trim(); // "2.0332"
Edit 2: With your update, I see the problem now. Scanner.nextFloat is what's breaking on the space. If you change your code to use Scanner.nextLine like so:
while (i <= 0) {
String input = in.nextLine();
input = input.replaceAll("[^\\d.]", "");
float i = Float.parseFloat(input);
if (i <= 0.0f) {
System.out.println("Please enter a number greater than 0.");
}
System.out.println(i);
}
That code will properly accept you entering things like "123,232 . 03 445". Use any of the solutions in place of my replaceAll and it will work.
Scanner.nextFloat will split your input automatically based on whitespace. Scanner can take a delimiter when you construct it (for example, new Scanner(System.in, ",./ ") will delimit on ,, ., /, and )" The default constructor, new Scanner(System.in), automatically delimits based on whitespace.
I guess you're using the first argument from you main method. If you main method looks somehow like this:
public static void main(String[] args){
System.out.println(deleteSpaces(args[0]);
}
Your problem is, that spaces separate the arguments that get handed to your main method. So running you class like this:
java MyNumberConverter 22.2 33
The first argument arg[0] is "22.2" and the second arg[1] "33"
But like other have suggested, String.replace is a better way of doing this anyway.