I have a method which processes a line to seperate the first word which it puts into a string called cmd and the rest which it enters into a vector of strings for the parameters and then sends them to a function to process the command. The parameters are getting wrapped in square braces for some reason.
static private boolean processLine(String line) {
if (debug) System.out.println("DEBUG: processLine \"" + line + "\"");
line = new String(line.trim());
String cmd = new String();
Vector<String> params = new Vector<String>(3);
boolean hasparam = false;
Scanner s = new Scanner(line).useDelimiter(" ");
int x = 0;
while (s.hasNext()) {
if (x == 0) { cmd = s.next(); }
else if (x >= 1) {
params.add(s.next());
hasparam = true;
}
x++;
}
// Next we process the command.
processCmd(cmd, params);
return exit;
}
static private void processCmd(String cmd, Vector<String> params) {
boolean invalid = false;
if (debug) {
System.out.print("DEBUG: processCmd " + cmd);
if (params.size() == 0) System.out.println();
else for (String param : params)
System.out.println(" " + params);
}
Output:
> add hosting
DEBUG: processLine "add hosting"
DEBUG: processCmd add [hosting]
I'm not sure why I am getting this behaviour, and I would like an explanation as well as a solution.
The parameters are getting wrapped in square braces for some reason.
This is because you are printing the Vector itself rather than the element of Vector. So toString() method of Vector is calling out in following line:
System.out.println(" " + params);
Change this line to:
System.out.println(" " + param);
Related
I try to remove a space into a string which contains a int type value.
I read a .csv file with the scanner methode.
I use a Class to set/get the data.
I format data into the setter of the class.
Input data example:
String Pu_ht = "1 635,90";
Basic Example:
/**
* #param Pu_ht the Pu_ht to set
*/
public void setPu_ht(String Pu_ht) {
this.Pu_ht = Pu_ht.replace(",", ".").replace(".00", "");
}
Tried example:
/**
* #param Pu_ht the Pu_ht to set
*/
public void setPu_ht(String Pu_ht) {
this.Pu_ht = Pu_ht.replace(",", ".").replace(".00", "").replaceAll("\\s+", "");
}
Other example:
/**
* #param Pu_ht the Pu_ht to set
*/
public void setPu_ht(String Pu_ht) {
this.Pu_ht = Pu_ht.replace(",", ".").replace(".00", "").replaceAll(" ", "");
}
Output data example: 1 635.90
I tried a lots of things but nothing work for my case.
Best regards
EDIT:
My code:
public void requete_pommes() throws IOException, ClassNotFoundException, SQLException {
// open file input stream
BufferedReader reader = new BufferedReader(new FileReader(filename));
// read file line by line
String line = null;
Scanner scanner = null;
int index = 0;
List<Pommes> pomList = new ArrayList<>();
boolean firstLine = false;
while ((line = reader.readLine()) != null) {
if (!(line.equals(";;;;TOTAL HT"))) {
if (!(line.equals(";;;;"))) {
Pommes pom = new Pommes();
scanner = new Scanner(line);
scanner.useDelimiter(";");
while (scanner.hasNext()) {
String data = scanner.next();
pom.setNumero_compte("21826");
if ((index == 0)) {
pom.setReference(data);
} else if ((index == 1)) {
pom.setDesignation(data);
} else if ((index == 2)) {
pom.setQte(data);
} else if ((index == 3)) {
if(data.equals("1 635,90")){
data = data.replaceAll("\\s","");
System.err.println("data: " + data);
}
pom.setPu_ht(data);
} else if ((index == 4)) {
pom.setMontant_HT(data);
} else {
System.out.println("invalid data::" + data);
}
pom.setNumero_commande("1554");
index++;
}
index = 0;
pomList.add(pom);
requeteCorps = "(( SELECT codea FROM article WHERE tarif7 != 'O' AND tarif8 = 'O' AND pvente > 0 AND COALESCE(trim( reffou), '') != '' AND reffou = '" + pom.getReference() + "' ), " + pom.getQte() + " , " + pom.getPu_ht() + ", '" + kapiece + "', 'stomag','vendu', getnum('LCK')),";
ar.add(requeteCorps);
}
}
}
The value "1 635,90" probably stems from a locale specific format, and the "space" actually is a non-breaking space, \u00A0. This is done often to prevent in flexible width text representation a line break to happen inside a number.
s = s.replace("\u00A0", "");
String Pu_ht = "1 635,90";
System.out.println(Pu_ht.replace(",", ".").replace(".00", "").replaceAll("\\s+", ""));
just put the above codes in main method and execute. the output will be 1635.90,then examine your codes.
I am practicing to write a program that gets a text file from user and provides data such as characters, words, and lines in the text.
I have searched and looked over the same topic but cannot find a way to make my code run.
public class Document{
private Scanner sc;
// Sets users input to a file name
public Document(String documentName) throws FileNotFoundException {
File inputFile = new File(documentName);
try {
sc = new Scanner(inputFile);
} catch (IOException exception) {
System.out.println("File does not exists");
}
}
public int getChar() {
int Char= 0;
while (sc.hasNextLine()) {
String line = sc.nextLine();
Char += line.length() + 1;
}
return Char;
}
// Gets the number of words in a text
public int getWords() {
int Words = 0;
while (sc.hasNext()) {
String line = sc.next();
Words += new StringTokenizer(line, " ,").countTokens();
}
return Words;
}
public int getLines() {
int Lines= 0;
while (sc.hasNextLine()) {
Lines++;
}
return Lines;
}
}
Main method:
public class Main {
public static void main(String[] args) throws FileNotFoundException {
DocStats doc = new DocStats("someText.txt");
// outputs 1451, should be 1450
System.out.println("Number of characters: "
+ doc.getChar());
// outputs 0, should be 257
System.out.println("Number of words: " + doc.getWords());
// outputs 0, should be 49
System.out.println("Number of lines: " + doc.getLines());
}
}
I know exactly why I get 1451 instead of 1451. The reason is because I do not have '\n' at the end of the last sentence but my method adds
numChars += line.length() + 1;
However, I cannot find a solution to why I get 0 for words and lines.
*My texts includes elements as: ? , - '
After all, could anyone help me to make this work?
**So far, I the problem that concerns me is how I can get a number of characters, if the last sentence does not have '\n' element. Is there a chance I could fix that with an if statement?
-Thank you!
After doc.getChar() you have reached the end of file. So there's nothing more to read in this file!
You should reset your scanner in your getChar/Words/Lines methods, such as:
public int getChar() {
sc = new Scanner(inputFile);
...
// solving your problem with the last '\n'
while (sc.hasNextLine()) {
String line = sc.nextLine();
if (sc.hasNextLine())
Char += line.length() + 1;
else
Char += line.length();
}
return char;
}
Please note that a line ending is not always \n! It might also be \r\n (especially under windows)!
public int getWords() {
sc = new Scanner(inputFile);
...
public int getLines() {
sc = new Scanner(inputFile);
...
I would use one sweep to calculate all 3, with different counters. just a loop over each char, check if its a new word etc, increase counts , use Charater.isWhiteSpace *
import java.io.*;
/**Cound lines, characters and words Assumes all non white space are words so even () is a word*/
public class ChrCounts{
String data;
int chrCnt;
int lineCnt;
int wordCnt;
public static void main(String args[]){
ChrCounts c = new ChrCounts();
try{
InputStream data = null;
if(args == null || args.length < 1){
data = new ByteArrayInputStream("quick brown foxes\n\r new toy\'s a fun game.\nblah blah.la la ga-ma".getBytes("utf-8"));
}else{
data = new BufferedInputStream( new FileInputStream(args[0]));
}
c.process(data);
c.print();
}catch(Exception e){
System.out.println("ee " + e);
e.printStackTrace();
}
}
public void print(){
System.out.println("line cnt " + lineCnt + "\nword cnt " + wordCnt + "\n chrs " + chrCnt);
}
public void process(InputStream data) throws Exception{
int chrCnt = 0;
int lineCnt = 0;
int wordCnt = 0;
boolean inWord = false;
boolean inNewline = false;
//char prev = ' ';
while(data.available() > 0){
int j = data.read();
if(j < 0)break;
chrCnt++;
final char c = (char)j;
//prev = c;
if(c == '\n' || c == '\r'){
chrCnt--;//some editors do not count line seperators as new lines
inWord = false;
if(!inNewline){
inNewline = true;
lineCnt++;
}else{
//chrCnt--;//some editors dont count adjaccent line seps as characters
}
}else{
inNewline = false;
if(Character.isWhitespace(c)){
inWord = false;
}else{
if(!inWord){
inWord = true;
wordCnt++;
}
}
}
}
//we had some data and last char was not in new line, count last line
if(chrCnt > 0 && !inNewline){
lineCnt++;
}
this.chrCnt = chrCnt;
this.lineCnt = lineCnt;
this.wordCnt = wordCnt;
}
}
I currently have 2 loops, one which gets a timestamp, and another while loop to find the mapped information based off that time stamp and output in a certain way.
Issue I have is I am currently looping through a text, and want it to start reading the file from the beginning again when the isdone="N" for the second loop, however, this does not seem to be the case.
Code so far:
public static void organiseFile() throws FileNotFoundException {
String directory = "C:\\Users\\xxx\\Desktop\\Files\\ex1";
Scanner fileIn = new Scanner(new File(directory + "_temp.txt"));
Scanner readIn = new Scanner(new File(directory + ".txt"));
PrintWriter out = new PrintWriter(directory + "_ordered.txt");
ArrayList<String> lines = new ArrayList<String>();
String readTimeStamp = "";
String timeStampMapping = "";
String outputFirst = "";
String outputSecond = "";
String outputThird = "";
String previousTimeStamp = "";
String doneList = "";
String isdone = "";
int counter = 1;
// Loop to get time stamps
while(fileIn.hasNextLine()) {
readTimeStamp = fileIn.nextLine();
if(readTimeStamp != null && readTimeStamp.trim().length() > 0) {
readTimeStamp = readTimeStamp.substring(12, 25);
System.out.println(readTimeStamp);
// Previous time stamp found, no need to loop through it again
if(doneList.contains(readTimeStamp))
isdone = "Y";
// Counter in place to stop outputting the first record, otherwise output file and clear variables down
else if(!previousTimeStamp.equals(readTimeStamp) && counter > 1) {
out.println(outputFirst + outputSecond + outputThird);
System.out.println("Outputting....");
outputFirst = "";
outputSecond = "";
outputThird = "";
counter = 1;
}
// New time stamp found, start finding values in second loop
else
isdone = "N";
// Secondary loop to find match of record
while(readIn.hasNextLine() && isdone.equals("N")) {
System.out.println("Mapping...");
timeStampMapping = readIn.nextLine();
System.out.println(timeStampMapping);
// When a record has been found with matching time stamps, start ordering
if(timeStampMapping.contains(readTimeStamp)) {
previousTimeStamp = readTimeStamp;
System.out.println(previousTimeStamp);
if(timeStampMapping.contains("[EVENT=agentStateEvent]")) {
outputFirst += timeStampMapping + "\r\n";
} else if(timeStampMapping.contains("[EVENT=TerminalConnectionCreated]")) {
outputSecond += timeStampMapping + "\r\n";
} else {
outputThird += timeStampMapping + "\r\n";
doneList += readTimeStamp + ",";
}
counter++;
}
}
}
}
System.out.println("Outputting final record");
out.println(outputFirst + outputSecond + outputThird);
System.out.println("Complete!");
out.close();
}
You can use Scanner.reset() to reset it to the beginning of the file. For example, after your second while-loop include:
if (isdone.equals("Y")) {
fileIn.reset();
}
Btw: why are you using String for isdone instead of boolean??
I have a working file rename java tool, now I want to add an if condition to run a commandline command if I checked a box as part of the rename process on each file it renames.
I will be changing the dos code later, but its a sample I found that works. Part of my problem is my filerename is its own class, so I will also need to figure out how to combine this class or reference the dos command somehow from my main rename class.
update
I updated the code with the changes from the answer, but the commandline command does not work and it crashes java with no error. The command does work from cmd line.
import java.io.IOException;
import java.io.InputStream;
public class doscommandrun {
public static void run() {
final String dosCommand = "cmd converter.exe file.doc -android -o file.txt";
try {
final Process process = Runtime.getRuntime().exec(
dosCommand + " ");
final InputStream in = process.getInputStream();
int ch;
while((ch = in.read()) != -1) {
System.out.print((char)ch);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
enter code hereFile rename code:
private void renameFile(){
boolean operationResult = false;
boolean overallResult = true;
int failCount = 0;
/* the operation of this part is ensured by the chooseDirectory()
* WE get the list of files in the directory
* get the conditions set by users
* and perform the file rename operation.
*/
//Let's get all the information from user
String[] fileList = directory.list(); //the list of files in the directory
String Prefix = txtPrefix.getText();
String Rename = txtRename.getText();
String Suffix = txtSuffix.getText();
String digits = (String) cboSequence.getSelectedItem();
int StartingNum;
String generatedSequence;
File oldFile;
//let's call the output frame
if(cbxOutput.isSelected() && OUTPUT_ON == false){
buildOutput();
OUTPUT_ON = true;
}
//display the list of files and readability of each file
for(int i = 0; i < fileList.length; i++){
oldFile = new File(directory.getPath()+"/"+ fileList[i]);
String readability = fileList[i] +" - readable?: "+oldFile.canRead();
System.out.println(readability);
if(OUTPUT_ON)
txaOutput.append("\n"+readability);
}
for(int i = 0; i < fileList.length; i++){
/* get the file extension that we need, and form a new name,
* we would check if the Ignore File Extension is selected
*/
oldFile = new File(directory.getPath()+"/"+ fileList[i]);
String fileExtension;
if(cbxIgnoreExtension.isSelected() == true ){
fileExtension = "";
}
else
fileExtension = getFileExtension(fileList[i]);
//this part get the original filename
String fileName = getFileName(fileList[i]);
String inputInfo = "The input filename->"+ fileList[i] + "\nfile name->" + fileName + "\nextension->" + fileExtension;
System.out.println(inputInfo);
if(OUTPUT_ON)
txaOutput.append("\n"+inputInfo);
/* generate sequence for the Name
*if the digits selection is NONE, we ignore it
*/
if(digits.equals("None") == true){
generatedSequence = "";
}
else{
StartingNum = Integer.parseInt(txtSequence.getText());
generatedSequence = nameSequence(StartingNum + i, digits);
}
//this is affected by the RenameOption, if Rename has something then only we RENAME
if(cbxRename.isSelected() == true){
fileName = Rename + generatedSequence; //the fileName will change.
}
else{
//if Rename has nothing, but the txtSequence has some Value, we take it to the naming too
fileName = fileName.substring(0,4)+ generatedSequence;
if(cbxAndroid.isSelected() == true ){
doscommandrun.run();
}
//the New File Name
String newFileName = Prefix + fileName.substring(0,4) + Suffix + fileExtension;
String tentativeName = "new Filename will be ->"+newFileName+"\n";
System.out.println(tentativeName);
if(OUTPUT_ON)
txaOutput.append("\n"+tentativeName);
// ! Perform the file rename, if the Experimental Mode is not selected
if(cbxExperiment.isSelected() == false){
operationResult = oldFile.renameTo(new File(directory.getPath()+"/"+newFileName));
String renameResult = "\t*Rename successfully?: " + operationResult+"\n\n";
System.out.println(renameResult);
if(operationResult == false)
failCount++;
if(OUTPUT_ON)
txaOutput.append("\n"+renameResult);
//make up the overall result
overallResult = (operationResult && overallResult);
}
}
if(cbxExperiment.isSelected() == false){
System.out.println("Overall Result: "+overallResult);
if(overallResult)
JOptionPane.showMessageDialog(null, "All files renamed successfully!");
else
JOptionPane.showMessageDialog(null, "File renamed with "+ failCount+ " failure(s)");
}//end if
}
}//end renameFile
You can create a static method in the doccommandrun class called run() which will execute what is currently in the main method when called.
public class DosCommandRun
{
public static void run()
{
//..do stuff from main
}
}
Now whenever you want to call the dos command you can just insert DosCommandRun.run() into your code.
I add /c after the cmd in my renametool class
I am still having issues but wither a different problem.
Text File(First three lines are simple to read, next three lines starts with p)
ThreadSize:2
ExistingRange:1-1000
NewRange:5000-10000
p:55 - AutoRefreshStoreCategories Data:Previous UserLogged:true Attribute:1 Attribute:16 Attribute:2060
p:25 - CrossPromoEditItemRule Data:New UserLogged:false Attribute:1 Attribute:10107 Attribute:10108
p:20 - CrossPromoManageRules Data:Previous UserLogged:true Attribute:1 Attribute:10107 Attribute:10108
Below is the code I wrote to parse the above file and after parsing it I am setting the corresponding values using its Setter. I just wanted to know whether I can improve this code more in terms of parsing and other things also by using other way like using RegEx? My main goal is to parse it and set the corresponding values. Any feedback or suggestions will be highly appreciated.
private List<Command> commands;
private static int noOfThreads = 3;
private static int startRange = 1;
private static int endRange = 1000;
private static int newStartRange = 5000;
private static int newEndRange = 10000;
private BufferedReader br = null;
private String sCurrentLine = null;
private int distributeRange = 100;
private List<String> values = new ArrayList<String>();
private String commandName;
private static String data;
private static boolean userLogged;
private static List<Integer> attributeID = new ArrayList<Integer>();
try {
// Initialize the system
commands = new LinkedList<Command>();
br = new BufferedReader(new FileReader("S:\\Testing\\Test1.txt"));
while ((sCurrentLine = br.readLine()) != null) {
if(sCurrentLine.contains("ThreadSize")) {
noOfThreads = Integer.parseInt(sCurrentLine.split(":")[1]);
} else if(sCurrentLine.contains("ExistingRange")) {
startRange = Integer.parseInt(sCurrentLine.split(":")[1].split("-")[0]);
endRange = Integer.parseInt(sCurrentLine.split(":")[1].split("-")[1]);
} else if(sCurrentLine.contains("NewRange")) {
newStartRange = Integer.parseInt(sCurrentLine.split(":")[1].split("-")[0]);
newEndRange = Integer.parseInt(sCurrentLine.split(":")[1].split("-")[1]);
} else {
allLines.add(Arrays.asList(sCurrentLine.split("\\s+")));
String key = sCurrentLine.split("-")[0].split(":")[1].trim();
String value = sCurrentLine.split("-")[1].trim();
values = Arrays.asList(sCurrentLine.split("-")[1].trim().split("\\s+"));
for(String s : values) {
if(s.contains("Data:")) {
data = s.split(":")[1];
} else if(s.contains("UserLogged:")) {
userLogged = Boolean.parseBoolean(s.split(":")[1]);
} else if(s.contains("Attribute:")) {
attributeID.add(Integer.parseInt(s.split(":")[1]));
} else {
commandName = s;
}
}
Command command = new Command();
command.setName(commandName);
command.setExecutionPercentage(Double.parseDouble(key));
command.setAttributeID(attributeID);
command.setDataCriteria(data);
command.setUserLogging(userLogged);
commands.add(command);
}
}
} catch(Exception e) {
System.out.println(e);
}
I think you should know what exactly you're expecting while using RegEx. http://java.sun.com/developer/technicalArticles/releases/1.4regex/ should be helpful.
To answer a comment:
p:55 - AutoRefreshStoreCategories Data:Previous UserLogged:true Attribute:1 Attribute:16 Attribute:2060
to parse above with regex (and 3 times Attribute:):
String parseLine = "p:55 - AutoRefreshStoreCategories Data:Previous UserLogged:true Attribute:1 Attribute:16 Attribute:2060";
Matcher m = Pattern
.compile(
"p:(\\d+)\\s-\\s(.*?)\\s+Data:(.*?)\\s+UserLogged:(.*?)\\s+Attribute:(\\d+)\\s+Attribute:(\\d+)\\s+Attribute:(\\d+)")
.matcher(parseLine);
if(m.find()) {
int p = Integer.parseInt(m.group(1));
String method = m.group(2);
String data = m.group(3);
boolean userLogged = Boolean.valueOf(m.group(4));
int at1 = Integer.parseInt(m.group(5));
int at2 = Integer.parseInt(m.group(6));
int at3 = Integer.parseInt(m.group(7));
System.out.println(p + " " + method + " " + data + " " + userLogged + " " + at1 + " " + at2 + " "
+ at3);
}
EDIT looking at your comment you still can use regex:
String parseLine = "p:55 - AutoRefreshStoreCategories Data:Previous UserLogged:true "
+ "Attribute:1 Attribute:16 Attribute:2060";
Matcher m = Pattern.compile("p:(\\d+)\\s-\\s(.*?)\\s+Data:(.*?)\\s+UserLogged:(.*?)").matcher(
parseLine);
if(m.find()) {
for(int i = 0; i < m.groupCount(); ++i) {
System.out.println(m.group(i + 1));
}
}
Matcher m2 = Pattern.compile("Attribute:(\\d+)").matcher(parseLine);
while(m2.find()) {
System.out.println("Attribute matched: " + m2.group(1));
}
But that depends if thre is no Attribute: names before "real" attributes (for example as method name - after p)
You can use the Scanner class. It has some helper methods to read text files
I would turn this inside out. Presently you are:
Scanning the line for a keyword: the entire line if it isn't found, which is the usual case as you have a number of keywords to process and they won't all be present on every line.
Scanning the entire line again for ':' and splitting it on all occurrences
Mostly parsing the part after ':' as an integer, or occasionally as a range.
So several complete scans of each line. Unless the file has zillions of lines this isn't a concern in itself but it demonstrates that you have got the processing back to front.