I'm have a little problem with the Java class Scanner:
I need to read a file (.dat) that contains Double values, but it seems like the method Scanner.nextDouble only recognize number written like this: 1234,5678 , with a "," but not with a ".". I wanted to know if there was a way to change that, because the file is generated by another software, so I can't make it change the "," for a ".".
Thanks
Robin
It seems like your default Locale uses a comma-based decimal separator for double values. Try using
scanner.useLocale(Locale.ENGLISH);
Replace , with .
Example:
Scanner sc = new Scanner(new File("myNumbers"));
while (sc.hasNext()) {
String s = sc.next();
Double d = (Double)s.replace(",",".");
}
Related
I am writing a program where I have to get a user input, saved as a double. The user must be able to put it using both ',' and '.' as a delimiter - however they want. I tried using useDelimiter which works only partially - it does indeed accept both values (e.g 4.5 and 4,5) but when I later use the entered value in a mathematical equation, I get wrong results - it seems to round the user input down to the closest integer and as an effect no matter whether I enter, 4 or 4.5 or 4,5 or 4.8 etc., I get the same result, which is actually only true to 4.
Does anyone happen to know why it doesn't work?
double protectiveResistor=0; //must be a double, required by my teacher
double voltage= 5;
System.out.println("Please provide the resistance.");
Scanner sc= new Scanner(System.in);
sc.useDelimiter("(\\p{javaWhitespace}|\\.|,)");
try
{
protectiveResistor=sc.nextDouble();
}
catch(InputMismatchException exception)
{
System.out.println("Wrong input!");
System.exit(1);
}
if (protectiveResistor<0){
System.err.println("Wrong input!");
System.exit(1);
}
double current = (double)voltage/protectiveResistor;
double power = (double)current*current*protectiveResistor;
Thank you!
The useDelimiter method is for telling the Scanner what character will separate the numbers from each other. It's not for specifying what character will be the decimal point. So with your code, if the user enters either 4.5 or 4,5, the Scanner will see that as two separate inputs, 4 and 5.
Unfortunately, the Scanner doesn't have the facility to let you specify two different characters as decimal separators. The only thing you can really do is scan the two numbers separately, then join them together into a decimal number afterwards. You will want to scan them as String values, so that you don't lose any zeroes after the decimal point.
What useDelimiter() does is split the input on the specified delimiter.
As an example, if you have the input of 4,5, the following code will print "4".
Scanner sc= new Scanner(System.in);
sc.useDelimiter(",");
System.out.println(sc.next())
If you also want to print the second part, after the ',', you need to add another line to get the next value, which would in this example print
"4
5":
Scanner sc= new Scanner(System.in);
sc.useDelimiter(",");
System.out.println(sc.next())
System.out.println(sc.next())
In your code you can do it like this:
Scanner sc= new Scanner(System.in);
sc.useDelimiter("(\\p{javaWhitespace}|\\.|,)");
try
{
String firstPart = "0";
String secondPart = "0";
if (sc.hasNext()) {
firstPart = sc.next();
}
if (sc.hasNext()) {
secondPart = sc.next();
}
protectiveResistor = Double.parseDouble(firstPart + "." + secondPart)
}
// Rest of your code here
What this code does is split the input on whitespace, '.' and ','. For a floating point value you expect one part before the decimal point and one after it. Therefore, you expect the scanner to have split the input in two parts. These two parts are assigned to two variables, firstPart and secondPart. In the last step, the two parts are brought together with the '.' as decimal point, as expected by Java and parsed back into a variable of type Double.
I need to read from a csv file. The file has some different types like int, float, String, char. How can I know what the type is?
I did write some code for it but my problem is with floating point numbers. In my computer java say that "7.9" is not a floating point number, but "7,9" is.
But on some computers "7.9" is a float. How can I solve this?
public static void Read(String filename) throws FileNotFoundException{
File file = new File(filename);
Scanner scanner1 = new Scanner(file);
String line ;
Scanner scanner;
int a;
float f;
String temp ;
while(scanner1.hasNextLine()){
line = scanner1.nextLine();
scanner = new Scanner(line);
scanner.useDelimiter(",|\\n");
while (scanner.hasNext()){
if (scanner.hasNextInt()){
a = scanner.nextInt();
System.err.printf("Int :%d",a);
}
else if(scanner.hasNextFloat()){
f = scanner.nextFloat();
System.err.printf("flt :%f",f);
}
else {
temp = scanner.next();
if(temp.length() == 1)
System.err.printf("char:%s",temp);
else
System.err.printf("string:%s",temp);
}
}
System.err.printf("\n");
scanner.close();
}
}
The more I read this more I realize I was wrong.
If your CSV data is like
1,2,3,4
Then it could be (1,2 and 3,4) eg (1.2, 3.4) or it could be the integers 1 through 4
If its properly quoted
"1,2","3,4"
Then your parser wont work because its not using quotes as the delimiters.
So its hard to say what is causeing your issue with out seeing the data.
You could add handeling of the quotes in your scanner but there are more cases inolved if your vlaues contain quotes themselves
Ideally use a proper CSV parse like http://opencsv.sourceforge.net/
Otherwise you need to walk through your data nad make sure your parse is covering all the cases you have today, and might have tomorrow.
A hack work around would be to modify your strings using replaceAll(".",","); but there are many pitfulls when doing that again, your scanner may confuse the elements as new entries in your CSV.
Specifically to change from representing decimals from 1,2 to 1.2 you can modify the Local for the number types you want with
scanner1.useLocale(Locale.US);
From what I can tell there is no way to have more than one locale for the scanner. One approach is to use two scanners, with two different Locales at the same time to parse the float differently.
You can change the scanner's locale using #useLocale(java.util.Locale)
Set the locale to one which uses . as the decimal point. I.e)
scanner.useDelimiter(",|\\n");
scanner.useLocale( Locale.US ); // Use '.' as decimal point
I've been trying to figure out how to create a program for a class. So far, I've gotten the rest of it down but I'm still unsure on how to do the start to it.
It requires for me to receive a name in any format: jOhn, joHN, JoHn
and convert it to John. I've been searching everywhere on how to separate them and return but I've had no luck.
Can anybody help?
This is for Java by the way.
EDIT: Not sure if I ended up doing it the right way, but I ended up with this:
System.out.println("Please type in your first name.");
String firstName = fName.next();
String partFirstName = firstName.toUpperCase().substring(0,1);
String partFirstName2 = firstName.toLowerCase().substring(1);
String correctFirst = (partFirstName + partFirstName2);
Simply in Java, without any 3rd party libraries, you can iterate over each element of an array of splitted Strings and then do:
Character.toUpperCase(user_input.charAt(0)) + user_input.substring(1).toLowerCase();
I don't know if this is what you are looking for but you could try the following:
EDIT: Thanks to Bohemian for pointing out a little bug in my code. The simplest code for the name formatting problem is Character.toUpperCase(input.charAt(0)) + input.substring(1).toLowerCase();. This is also what mhasen answered with so credit to him and also to Bohemian. Below contains the code snippet and all.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
String newInput = Character.toUpperCase(charAt(0))
+ input.substring(1).toLowerCase();
System.out.println();
System.out.println(newInput);
scan.close();
}
}
You can use Apache Commons Lang library's WordUtils.capitalize()
e.g: WordUtils.capitalize("john") will return "John".
And in order to split the string you can use split() method of String:
String input = "jOhn,JOhn,jOHn";
String[] values = input.split(",");
values will be array of String contain "jOhn","JOhn" and "jOHn"
I'd like to pop from text file which looks like "70.869, 78.22, 368.12...". I wrote this code using delimiters but it doesn't work for double ( my console after compile project is empty ). If I change it to int it works perfectly fine. I'd like to put this numbers to the array.
Scanner src = new Scanner(new File("ala1.txt"));
src.useDelimiter(", *");
float [] taller = new float [15];
int k = 0;
// Read and sum numbers.
while(src.hasNextDouble()){
//tall[i++] = scanner.nextInt();
System.out.println(src.nextDouble());
}
src.close();
Your delimiter looks fine, which suggests that problem is somewhere else.
From your question it looks like hasNextDouble doesn't see 70.869 as proper double. Possible problem could be that your locales instead of . expects , in double value (and based on your code it looks like your locale is Polish which confirms this theory).
So if that is the case make your Scanner use other locale which expects . in double instead of , like Locale.ENGLISH:
Scanner src = new Scanner("70.869, 78.22, 368.12");
src.useLocale(Locale.ENGLISH);
src.useDelimiter(", *");
while(src.hasNextDouble()){
System.out.println(src.nextDouble());
}
Output:
70.869
78.22
368.12
Let's say I got a textfile.txt that I want to read from. This is the text in the file:
23:years:old
15:years:young
Using the useDelimiter method, how can I tell my program that : and newlines are delimiters? Putting the text in one line and using useDelimter(":"); works. The problem is when I got several lines of text.
Scanner input = new Scanner(new File("textfile.txt));
input.useDelimiter(:);
while(data.hasNextLine()) {
int age = input.nextInt();
String something = input.next();
String somethingelse = input.next();
}
Using this code I will get an inputMisMatch error.
Try
scanner.useDelimiter("[:]+");
The complete code is
Scanner scanner = new Scanner(new File("C:/temp/text.txt"));
scanner.useDelimiter("[:]+");
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
The output is
23
years
old
15
years
young
Use this code
Scanner input;
String tokenizer[];
try {
input = new Scanner(new File("D:\\textfile.txt"));
input.useDelimiter("\\n");
while(input.hasNextLine()) {
tokenizer = input.next().split(":");
System.out.println(tokenizer[0]+" |"+tokenizer[1]+" | "+tokenizer[2]);
}
}catch(Exception e){}
It will give you output like
23 |years | old
15 |years | young
You have two ways to do this:
Concatenate the string to make it one line.
delimit "newline" first, then delimit ":" each return string token.
If all you want is to get everything split up all at once then I guess you can use
useDelimiter(":\\n")
That should split on both : and newspace but it is not the most efficient way of processing data, especially if each line of text is set out in the same format and represents a complete entry. If that is the case then my suggestion would be to only split on a new line to begin with, like this;
s.useDelimiter("\\n");
while(s.hasNext()){
String[] result = s.next.split(":");
//do whatever you need to with the data and store it somewhere
}
This will allow you to process the data line by line and will also split it at the required places. However if you do plan on going through line by line I recommend you look at BufferedReader as it has a readLine() function that makes things a lot easier.
As long as all the lines have all three fields you can just use input.useDelimiter(":\n");
you probably wants to create a delimiter pattern which includes both ':' and newline
I didn't test it, but [\s|:]+ is a regular expression that matches one or more whitespace characters, and also ':'.
Try put:
input.useDelimiter("[\\s|:]+");