java - funcion - printf y scanf en dev c++
¿Cuál es el equivalente de Java de sscanf para analizar valores de una cadena usando un patrón conocido? (7)
Así que vengo de un fondo en C (originalmente originalmente, aunque no he usado ese lenguaje durante casi 5 años) y estoy tratando de analizar algunos valores de una cadena en Java. En CI utilizaríamos sscanf. En Java, la gente me dijo "usar Scanner o StringTokenizer", pero no puedo ver cómo usarlos para lograr mi propósito.
Mi cadena de entrada se parece a "17-MAR-11 15.52.25.000000000". En CI haría algo como:
sscanf(thestring, "%d-%s-%d %d.%d.%d.%d", day, month, year, hour, min, sec, fracpart);
Pero en Java, todo lo que puedo hacer es cosas como:
scanner.nextInt();
Esto no me permite verificar el patrón, y para "MAR" acabo teniendo que hacer cosas como:
str.substring(3,6);
¡Horrible! Seguramente hay una manera mejor?
¿Está familiarizado con el concepto de expresiones regulares? Java le proporciona la capacidad de usar expresiones regulares utilizando la clase Patrón. Echa un vistazo a este: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html
Puedes probar tu String así:
Matcher matcher = Pattern.match(yourString);
matcher.find();
y luego use los métodos proporcionados por Matcher para manipular la cadena que encontró o NO.
Aquí hay una solución usando escáneres:
Scanner scanner = new Scanner("17-MAR-11 15.52.25.000000000");
Scanner dayScanner = new Scanner(scanner.next());
Scanner timeScanner = new Scanner(scanner.next());
dayScanner.useDelimiter("-");
System.out.println("day=" + dayScanner.nextInt());
System.out.println("month=" + dayScanner.next());
System.out.println("year=" + dayScanner.nextInt());
timeScanner.useDelimiter("//.");
System.out.println("hour=" + timeScanner.nextInt());
System.out.println("min=" + timeScanner.nextInt());
System.out.println("sec=" + timeScanner.nextInt());
System.out.println("fracpart=" + timeScanner.nextInt());
El problema es que Java no tiene parámetros (o pasa por referencia) como C o C #.
Pero hay una manera mejor (y más sólida). Usa expresiones regulares:
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);
....
Por supuesto, el código C es más conciso, pero esta técnica tiene un beneficio: los patrones especifican un formato más preciso que ''% s'' y ''% d''. Por lo tanto, puede usar / d {2} para especificar que el día DEBE estar compuesto de exactamente 2 dígitos.
Esto está lejos de ser una solución tan elegante como la que se obtendría con el uso de expresiones regulares, pero debería funcionar.
public static void stringStuffThing(){
String x = "17-MAR-11 15.52.25.000000000";
String y[] = x.split(" ");
for(String s : y){
System.out.println(s);
}
String date[] = y[0].split("-");
String values[] = y[1].split("//.");
for(String s : date){
System.out.println(s);
}
for(String s : values){
System.out.println(s);
}
Ninguno de estos ejemplos fue realmente satisfactorio para mí, así que hice mi propia utilidad java sscanf:
https://github.com/driedler/java-sscanf/tree/master/src/util/sscanf
Aquí hay un ejemplo de analizar una cadena hexadecimal:
String buffer = "my hex string: DEADBEEF/n"
Object output[] = Sscanf.scan(buffer, "my hex string: %X/n", 1);
System.out.println("parse count: " + output.length);
System.out.println("hex str1: " + (Long)output[0]);
// Output:
// parse count: 1
// hex str1: 3735928559
Para "17-MAR-11 15.52.25.000000000":
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yy HH.mm.ss.SSS");
try
{
Date parsed = format.parse(dateString);
System.out.println(parsed.toString());
}
catch (ParseException pe)
{
System.out.println("ERROR: Cannot parse /"" + dateString + "/"");
}
System.in.read () es otra opción.