what is the Java equivalent of sscanf for parsing values from a string using a known pattern?
The problem is Java hasn't out parameters (or passing by reference) as C or C#.
But there is a better way (and more solid). Use regular expressions:
Pattern p = Pattern.compile("(\\d+)-(\\p{Alpha}+)-(\\d+) (\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)")
Matcher m = p.matcher("17-MAR-11 15.52.25.000000000");
day = m.group(1);
month= m.group(2);
....
Of course C code is more concise, but this technique has one profit:
Patterns specifies format more precise than '%s' and '%d'. So you can use \d{2} to specify that day MUST be compose of exactly 2 digits.
sscanf equivalent in Java
Scanner scanner = new Scanner ("2 A text 3 4");
scanner.nextInt (); // 2
scanner.next (); // A
scanner.next (); // text
scanner.nextInt (); // 3
scanner.nextInt (); // 4
// and so on.
Here is the official documentation of the Scanner class.
Is there an equivalent method to C's scanf in Java?
Take a look at this site, it explains two methods for reading from console in java, using Scanner
or the classical InputStreamReader
from System.in.
Following code is taken from cited website:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ReadConsoleSystem {
public static void main(String[] args) {
System.out.println("Enter something here : ");
try{
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
String s = bufferRead.readLine();
System.out.println(s);
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
--
import java.util.Scanner;
public class ReadConsoleScanner {
public static void main(String[] args) {
System.out.println("Enter something here : ");
String sWhatever;
Scanner scanIn = new Scanner(System.in);
sWhatever = scanIn.nextLine();
scanIn.close();
System.out.println(sWhatever);
}
}
Regards.
Elegant equivalent to C's vsscanf() in Java
You can use java.text.MessageFormat
. For example:
public static void main(String[] args) throws ParseException {
String input="hello 1:2.3.4";
MessageFormat form = new MessageFormat("{0} {1,number}:{2,number,integer}.{3,number}");
Object[] data = form.parse(input);
for(Object o : data) {
System.out.println(o.getClass()+" : "+o.toString());
}
}
Which produces the output:
class java.lang.String : hello
class java.lang.Long : 1
class java.lang.Long : 2
class java.lang.Double : 3.4
Of course, the format isn't as compact as that used by scanf
, but it is out of the box Java.
Reading from a txt file in Java
if(scan.hasNextDouble())
{
price = scan.nextDouble();
}
change this to
price = Double.parseDouble(scan.next().substring(1));
And change
System.out.println(name + " " + quantity + " " + item_name + " " + price);
this to
System.out.println(name + " " + quantity + " " + item_name + " $" + price);
How sscanf() splits a string in C
This explanation is little over-simplified and there is more than this going on inside the sscanf
as the source code is itself more than 3,000 lines of code.
The format specifier mentioned by you in the example is listed below with their corresponding match pattern%d
: [0-9]
,[-,+]
%f
: [0-9]
,[-,+,.]
%c
: [a-z]
,[A-Z]
, Other ASCII Characters
Parsing
- First, for
%d
, it will first search for[+,-]
signs, and if not found then it will look for[0-9]
single digits in sequence. As soon as it sees a non-single digit (A = 65) in the string, it will end its search for%d
and save the value of theint
to the corresponding address passed tosscanf
. - Second, for
%c
, now it will take the next format specifier passed i.e.%c
and begin again from the location where it previously stopped. This time it just has to read a single byte from the string and save it to the corresponding address passed tosscanf
- Third, for
%f
, it will first search for[+,-]
signs, and if not found it will then look for.
and the single digits[0-9]
. This continues until it gets something which is not part of the%f
, which in this case will be\0
. And save it to the corresponding address passed tosscanf
Finally, once everything is completed and the string is split, it returns the total number of arguments parsed. So, it a good programming practice to compare the number of the passed argument list with the returned value.
Reference:
sscanf
source codevfscanf
source code
Related Topics
How to Give System Property to My Test via Gradle and -D
Java 8: How to Work with Exception Throwing Methods in Streams
Create a List of Primitive Int
Override "Private" Method in Java
Remove Duplicates from Arraylists
Concurrent Threads Adding to Arraylist at Same Time - What Happens
Java: Global Exception Handler
What Is the Purpose of Mavens Dependency Declarations Classifier Property
Accessing Kotlin Extension Functions from Java
How to Use Regular Expressions in Web.Xml Url Patterns
Cancelling a Long Running Regex Match
Why String.Replaceall() in Java Requires 4 Slashes "\\\\" in Regex to Actually Replace "\"
How to Determine If a String Has Non-Alphanumeric Characters