I am trying to write 2 different arrays to a csv. The first one I want in the first column, and second array in the second column, like so:
array1val1 array2val1
array1val2 array2val2
I am using the following code:
String userHomeFolder2 = System.getProperty("user.home") + "/Desktop";
String csvFile = (userHomeFolder2 + "/" + fileName.getText() + ".csv");
FileWriter writer = new FileWriter(csvFile);
final String NEW_LINE_SEPARATOR = "\n";
FileWriter fileWriter;
CSVPrinter csvFilePrinter;
CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);
fileWriter = new FileWriter(fileName.getText());
csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);
try (PrintWriter pw = new PrintWriter(csvFile)) {
pw.printf("%s\n", FILE_HEADER);
for(int z = 0; z < compSource.size(); z+=1) {
//below forces the result to get stored in below variable as a String type
String newStr=compSource.get(z);
String newStr2 = compSource2.get(z);
newStr.replaceAll(" ", "");
newStr2.replaceAll(" ", "");
String[] explode = newStr.split(",");
String[] explode2 = newStr2.split(",");
pw.printf("%s\n", explode, explode2);
}
}
catch (Exception e) {
System.out.println("Error in csvFileWriter");
e.printStackTrace();
} finally {
try {
fileWriter.flush();
fileWriter.close();
csvFilePrinter.close();
} catch (IOException e ) {
System.out.println("Error while flushing/closing");
}
}
However I am getting a strange output into the csv file:
[Ljava.lang.String;#17183ab4
I can run
pw.printf("%s\n", explode);
pw.printf("%s\n", explode2);
Instead of : pw.printf("%s\n", explode, explode2);
and it prints the actual strings but all in one same column.
Does anyone know how to solve this?
1.Your explode and explode2 are actually String Arrays. You are printing the arrays and not the values of it. So you get at the end the ADRESS of the array printed.
You should go through the arrays with a loop and print them out.
for(int i = 0; i<explode.length;++i) {
pw.printf("%s%s\n", explode[i], explode2[i]);
}
2.Also the method printf should be look something like
pw.printf("%s%s\n", explode, explode2);
because youre are printing two arguments, but in ("%s\n", explode, explode2) is only one printed.
Try it out and say if it worked
After these lines:
newStr.replaceAll(" ", "");
newStr2.replaceAll(" ", "");
String[] explode = newStr.split(",");
String[] explode2 = newStr2.split(",");
Use this code:
int maxLength = Math.max(explode.length, explode2.length);
for (int i = 0; i < maxLength; i++) {
String token1 = (i < explode.length) ? explode[i] : "";
String token2 = (i < explode2.length) ? explode2[i] : "";
pw.printf("%s %s\n", token1, token2);
}
This also cover the case that the arrays are of different length.
I have removed all unused variables and made some assumptions about content of compSource.
Moreover, don't forget String is immutable. If you just do "newStr.replaceAll(" ", "");", the replacement will be lost.
public class Tester {
#Test
public void test() throws IOException {
// I assumed compSource and compSource2 are like bellow
List<String> compSource = Arrays.asList("array1val1,array1val2");
List<String> compSource2 = Arrays.asList("array2val1,array2val2");
String userHomeFolder2 = System.getProperty("user.home") + "/Desktop";
String csvFile = (userHomeFolder2 + "/test.csv");
try (PrintWriter pw = new PrintWriter(csvFile)) {
pw.printf("%s\n", "val1,val2");
for (int z = 0; z < compSource.size(); z++) {
String newStr = compSource.get(z);
String newStr2 = compSource2.get(z);
// String is immutable --> store the result otherwise it will be lost
newStr = newStr.replaceAll(" ", "");
newStr2 = newStr2.replaceAll(" ", "");
String[] explode = newStr.split(",");
String[] explode2 = newStr2.split(",");
for (int k = 0; k < explode.length; k++) {
pw.println(explode[k] + "\t" + explode2[k]);
}
}
}
}
}
Related
I would like to count countX and countX using the same loop instead of creating three different loops. Is there any easy way approaching that?
public class Absence {
private static File file = new File("/Users/naplo.txt");
private static File file_out = new File("/Users/naplo_out.txt");
private static BufferedReader br = null;
private static BufferedWriter bw = null;
public static void main(String[] args) throws IOException {
int countSign = 0;
int countX = 0;
int countI = 0;
String sign = "#";
String absenceX = "X";
String absenceI = "I";
try {
br = new BufferedReader(new FileReader(file));
bw = new BufferedWriter(new FileWriter(file_out));
String st;
while ((st = br.readLine()) != null) {
for (String element : st.split(" ")) {
if (element.matches(sign)) {
countSign++;
continue;
}
if (element.matches(absenceX)) {
countX++;
continue;
}
if (element.matches(absenceI)) {
countI++;
}
}
}
System.out.println("2. exerc.: There are " + countSign + " rows int the file with that sign.");
System.out.println("3. exerc.: There are " + countX + " with sick note, and " + countI + " without sick note!");
} catch (FileNotFoundException ex) {
Logger.getLogger(Absence.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
text file example:
# 03 26
Jujuba Ibolya IXXXXXX
Maracuja Kolos XXXXXXX
I think you meant using less than 3 if statements. You can actually so it with no ifs.
In your for loop write this:
Countsign += (element.matches(sign)) ? 1 : 0;
CountX += (element.matches(absenceX)) ? 1 : 0;
CountI += (element.matches(absenceI)) ? 1 : 0;
Both answers check if the word (element) matches all regular expressions while this can (and should, if you ask me) be avoided since a word can match only one regex. I am referring to the continue part your original code has, which is good since you do not have to do any further checks.
So, I am leaving here one way to do it with Java 8 Streams in "one liner".
But let's assume the following regular expressions:
String absenceX = "X*";
String absenceI = "I.*";
and one more (for the sake of the example):
String onlyNumbers = "[0-9]*";
In order to have some matches on them.
The text is as you gave it.
public class Test {
public static void main(String[] args) throws IOException {
File desktop = new File(System.getProperty("user.home"), "Desktop");
File txtFile = new File(desktop, "test.txt");
String sign = "#";
String absenceX = "X*";
String absenceI = "I.*";
String onlyNumbers = "[0-9]*";
List<String> regexes = Arrays.asList(sign, absenceX, absenceI, onlyNumbers);
List<String> lines = Files.readAllLines(txtFile.toPath());
//#formatter:off
Map<String, Long> result = lines.stream()
.flatMap(line-> Stream.of(line.split(" "))) //map these lines to words
.map(word -> regexes.stream().filter(word::matches).findFirst()) //find the first regex this word matches
.filter(Optional::isPresent) //If it matches no regex, it will be ignored
.collect(Collectors.groupingBy(Optional::get, Collectors.counting())); //collect
System.out.println(result);
}
}
The result:
{X*=1, #=1, I.=2, [0-9]=2}
X*=1 came from word: XXXXXXX
#=1 came from word: #
I.*=2 came from words: IXXXXXX and Ibolya
[0-9]*=2 came from words: 03 and 06
Ignore the fact I load all lines in memory.
So I made it with the following lines to work. It escaped my attention that every character need to be separated from each other. Your ternary operation suggestion also nice so I will use it.
String myString;
while ((myString = br.readLine()) != null) {
String newString = myString.replaceAll("", " ").trim();
for (String element : newString.split(" ")) {
countSign += (element.matches(sign)) ? 1 : 0;
countX += (element.matches(absenceX)) ? 1 : 0;
countI += (element.matches(absenceI)) ? 1 : 0;
I am editing this question to be more specific and I've learned some Jave to find the solution to my problem. I have a file in CSV format like this:
or in excel like this:
Now I am using Java program to read the second line of file and separate each Comma Separated Value and write it to console as well as on other output file and it was done easily. Now I'm trying to break the last value of:
S/1,M/1,L/1,XL/1 | 2XL/1,3XL/1,4XL/1,5XL/1 | MT/1,LT/1 (Original)
S/1,M/1,L/1,XL/1,2XL/1,3XL/1,4XL/1,5XL/1,MT/1,LT/1 (Modified using program to remove spaces and replacing the Pipes (|) with comma.
In each value, There is the size name before Forward Slash (/) and its quantity is after that. What I'm trying is using the Forward Slash (/) to separate the size with its quantity. And the problem is that the size may contain the forward slash as well (e.g. 12/BT or 2BT/2x). I've tried many algorithms like reversing the whole array or storing the slash count but not getting the success. The whole code to read file and break the comma separated values into separate columns of file is as following:
import java.io.*;
import javax.swing.*;
public class ReadFile3c{
public static void main(String args[]){
try{
//Getting File Name
String fileName = JOptionPane.showInputDialog("Enter File Name") + ".csv";
//Creating Stream with File
FileReader fr = new FileReader(fileName);
//Applying Buffer Filter
BufferedReader br = new BufferedReader(fr);
//Reading First line then Second Line
String s = br.readLine();
s = br.readLine();
s = s + ",";//adding comma at the end of the file
s = s.replaceAll("\\s",""); //Eliminating Spaces
s = s.replaceAll("\\|",","); //Replacing Pipes with comma
char charArray[] = s.toCharArray();
//Declaring Strings and variablse for value separating function
int n = 0; //Array Variable
int m = 0; //Array Variable
String[] inverted = new String[3]; //String to store inverted Commas Values
String[] comma = new String[10]; //String to store comma Values
String value = ""; //Storing character values
try{
//Loop to cycle each character of file
for(int j = 0; j<charArray.length;j++){
//Inverted comma value separator
if (charArray[j] == '"') {
j++;
//loop to gather values b/w invreted comma
while((charArray[j] != '"')){
value = value + charArray[j];
j++;
}
inverted[n] = value;
n++;
j++;
value = "";
}else{
j = j - 1;
//comma Value separator
if (charArray[j] == ','){
j++;
//loop to gether values b/w commas
while((charArray[j] !=',')){
value = value + charArray[j];
j++;
}
comma[m] = value;
m++;
value = "";
}
}
}
}catch(Exception ex){
System.out.println("in inner Exception Block" + ex);
}
//declaring variables to storing values
String name, patternCode, placeSizeQty,width,length,utill,pArea,pPerimeter,totalPcs,placePcs,tSizes;
name = inverted[0];
patternCode = inverted[1];
placeSizeQty = inverted[2];
width = comma[0];
length = comma[1];
utill = comma[2];
pArea = comma[3];
pPerimeter = comma[4];
totalPcs = comma[5];
placePcs = comma[6];
tSizes = comma[7];
//printing all values on Console
System.out.println("\nMarkerName: " + name);
System.out.println("Width :" + width);
System.out.println("Length :" + length);
System.out.println("Utill :" + utill);
System.out.println("Place Area :" + pArea);
System.out.println("Place Perimeter :" + pPerimeter);
System.out.println("PatternCode: " + patternCode);
System.out.println("PlaceSizeQty: " + placeSizeQty);
System.out.println("Total Pcs :" + totalPcs);
System.out.println("Place Pcs :" + placePcs);
System.out.println("Total Sizes :" + tSizes);
//Creating Output file
String fileOutput = JOptionPane.showInputDialog("Enter Output File Name") + ".txt";
//File Writer
try{
//Creating Stream with output file
FileWriter fw = new FileWriter(fileOutput);
//Applying Buffring Stream
PrintWriter pw = new PrintWriter(fw);
//Declaration
String outputLine = null;
//Writing Inverted inputs
for (int u = 0; u <=2 ;u++ ) {
outputLine = inverted[u];
pw.println(outputLine);
System.out.println("Writing: " + outputLine);
}//end of for
//writing comma inputs
for (int t = 0;t <=7 ; t++ ) {
outputLine = comma[t];
pw.println(outputLine);
System.out.println("Writing: " + outputLine);
}//end of for
pw.flush();
pw.close();
fw.close();
fr.close();
br.close();
}catch(Exception ex){
System.out.println("Output: " + ex);
}//End of output catch
}catch(IOException ex){
System.out.println(ex);
}//end of catch
}//end of catch
}//end of Class
And the code to Break the Size and quantity and store it in Double array (Not completed) is as Following:
import java.io.*;
import javax.swing.*;
public class ReadFileInvert{
public static void main(String args[]){
try{
String fileName = JOptionPane.showInputDialog("Enter File Name") + ".csv";
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
String s = br.readLine();
System.out.println(s);
s = s.replaceAll("\\s","");
s = s.replaceAll("\\|",",");
System.out.println(s);
char charArray[] = s.toCharArray();
char charArrayI[] = new char[charArray.length + 1];
int j = 0;
String value = "";
for(int i = charArray.length; i > 0; i--){
charArrayI[j] = charArray[i];
value = value + charArrayI[j];
j++;
}
System.out.println("1" + value);
}catch(Exception ex){
System.out.println(ex);
}
}
}
Now in simple I just want to Separate the sizes (Which may contains the Forward Slashes) with its quantity (After last slash of each value) and store it in double array Like charArray[sizeName][Qty]. Sorry if i didn't explained my problem well as I'm Learning the Coding. but I'll provide as much info as you want.
Have you considered looking at the CAD software export to see if there is a solution on the file creation side? Or is this file coming from a third party?
OK. So, after the hard work of whole day, I've found the following solution to my problem:
import java.io.*;
import javax.swing.*;
public class ReadFileInvert2{
public static void main(String args[]){
try{
String fileName = JOptionPane.showInputDialog("Enter File Name") + ".csv";
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
String s = br.readLine();
System.out.println(s);
s = s.replaceAll("\\s","");
s = s.replaceAll("\\|",",");
System.out.println(s);
char charArray[] = s.toCharArray();
int x = charArray.length - 1;
charArray[x] = ',';
int no = 1;
int size = 1;
int qty = 2;
String sizeS = "";
String qtyS = "";
//String resSet[][] = new String[4][2];
String resSize[] = new String[20];
String resQty[] = new String[20];
int slashNo = 0;
String value = "";
for (int j = 1; j < charArray.length; j++){
int n = j;
if (charArray[j] == ','){
j++;
}
while (charArray[j] != ','){
if (charArray[j] == '/') {
slashNo = j;
//j++;
}
value = value + charArray[j];
//System.out.println(value);
j++;
}
for (int k = n;k < slashNo; k++ ) {
sizeS = sizeS + charArray[k];
//System.out.println(sizeS);
}
for (int l = slashNo + 1; l < j; l++ ) {
qtyS = qtyS + charArray[l];
//System.out.println(qtyS);
}
resSize[no] = sizeS;
System.out.println(resSize[no]);
resQty[no] = qtyS;
System.out.println(resQty[no]);
System.out.println("Size is: " + resSize[no] + ", and Qty is: " + resQty[no]);
no++;
slashNo = 0;
sizeS = "";
qtyS = "";
}
String fileOutput = JOptionPane.showInputDialog("Enter Output File Name: ") + ".txt";
try{
FileWriter fw = new FileWriter(fileOutput);
PrintWriter pw = new PrintWriter(fw);
String outputSize = null;
String outputQty = null;
for (int t = 1; t < no; t++) {
outputSize = resSize[t];
outputQty = resQty[t];
pw.println(outputSize + " = " + outputQty);
System.out.println("Writing: "+ outputSize + " = " + outputQty);
}
pw.flush();
pw.close();
fw.close();
fr.close();
br.close();
}catch(Exception ex){
System.out.println("Output " + ex);
}
}catch(Exception ex){
System.out.println(ex);
}
}
}
Now its in Generic form but will improve it later. But still its working fine. Thanks for your Help stack overflow Community.
In the method, i have all these initialize
Scanner input = new Scanner(System.in);
File file = new File("order.dat");
File viewOrder = new File("ViewOrder.dat");
String orderNo, itemNo, itemNameHolder, qtyHolder, priceHolder, status;
int hold, count = 0, countArray = 0;
double tempPriceHolder, totalPrice = 0;
String tempStatus = "";
String[] holdItemNo = null;
String[] holdName = null;
Integer[] holdQty = null;
Double[] holdTotal = null;
String[] holdStatus = null;
After, i try to read all my content in the file and store the content into holdX array
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
while ((line = br.readLine()) != null) {
String tokens[] = line.split(";");
orderNo = tokens[0];
itemNo = tokens[1];
itemNameHolder = tokens[2];
qtyHolder = tokens[3];
priceHolder = tokens[4];
status = tokens[5];
if (orderNo.equalsIgnoreCase(userOrderNo)) {
tempPriceHolder = Double.parseDouble(priceHolder);
hold = Integer.parseInt(qtyHolder);
tempPriceHolder = tempPriceHolder * hold;
totalPrice += tempPriceHolder;
countArray++;
holdItemNo = new String[countArray];
holdName = new String[countArray];
holdQty = new Integer[countArray];
holdTotal = new Double[countArray];
holdStatus = new String[countArray];
if (status.matches("s")) {
tempStatus = "Success";
} else if (status.matches("p")) {
tempStatus = "Partially Full";
} else if (status.matches("o")) {
tempStatus = "Out of Stock";
}
holdItemNo[count] = itemNo;
holdName[count] = itemNameHolder;
holdQty[count] = hold;
holdTotal[count] = tempPriceHolder;
holdStatus[count] = tempStatus;
count++;
}
}
} catch (Exception e) {
System.out.println("Error");
}
Final, i write all my array into a new file.
System.out.printf("%s %15s %15s %10s %10s\n", "Item No", "Description", "Quantity", "Total", "Status");
for (int i = 0; i < holdItemNo.length; i++) {
System.out.printf("\n%-11s %-18s %-13s $%-8s %s \n", holdItemNo[i], holdName[i], holdQty[i], holdTotal[i], holdStatus[i]);
}
System.out.println("-----------------------------------------------------------------------");
System.out.printf("%46s %s\n", "$", totalPrice);
System.out.print("Print Order to file Y/N: ");
String choice = input.next();
if (choice.equalsIgnoreCase("y")) {
try {
PrintWriter bw = new PrintWriter(new FileWriter("ViewOrder.dat", true));
for (int i = 0; i < holdItemNo.length; i++) {
bw.write(userOrderNo + ";" + holdItemNo[i] + ";" + holdName[i] + ";" + holdQty[i] + ";" + holdTotal[i] + ";" + holdStatus[i] + "\n");
bw.flush();
}
bw.flush();
bw.close();
System.out.println("Sucessfull!");
} catch (Exception e) {
System.out.println("Error");
}
} else if (choice.equalsIgnoreCase("n")) {
System.out.println("");
}
but the problem is even my code is working but the output is not what i expected. It printed out the printed out the last content and also the sub price is working as well but the rest is only printed out NULL.
Example
Also, it gave me warning of Derefencing possible null pointer on the array.length
for (int i = 0; i < holdItemNo.length; i++) {
bw.write(userOrderNo + ";" + holdItemNo[i] + ";" + holdName[i] + ";" + holdQty[i] + ";" + holdTotal[i] + ";" + holdStatus[i] + "\n");
bw.flush();
}
Guessing:
holdItemNo = new String[countArray];
and the following lines: you are creating these new array objects within your reading loop (inside a condition).
So probably that condition never goes true; therefore your arrays stay all null. But even when the condition is met - you probably expect that to happen more then once. And guess what: you are creating completely new arrays then. While throwing away the previously created array. Each time the if condition turns true you will lose previously stored values!
So the answer is: create your arrays before entering the loop. This means that you either have to query "how many slots to create" upfront; or you have to create an array with say 100 empty slots; and within your loop you then have to check if you still have free slots.
Or you start using java.util.List resp. ArrayList - which allows for dynamic adding of elements.
I've got the following code that opens and read a file and separates it to words.
My problem is at making an array of these words in alphabetical order.
import java.io.*;
class MyMain {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Kennedy.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
int line_count=0;
int byte_count;
int total_byte_count=0;
int fromIndex;
while( (line = br.readLine())!= null ){
line_count++;
fromIndex=0;
String [] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
String line_rest=line;
for (int i=1; i <= tokens.length; i++) {
byte_count = line_rest.indexOf(tokens[i-1]);
//if ( tokens[i-1].length() != 0)
//System.out.println("\n(line:" + line_count + ", word:" + i + ", start_byte:" + (total_byte_count + fromIndex) + "' word_length:" + tokens[i-1].length() + ") = " + tokens[i-1]);
fromIndex = fromIndex + byte_count + 1 + tokens[i-1].length();
if (fromIndex < line.length())
line_rest = line.substring(fromIndex);
}
total_byte_count += fromIndex;
}
}
}
I would read the File with a Scanner1 (and I would prefer the File(String,String) constructor to provide the parent folder). And, you should remember to close your resources explicitly in a finally block or you might use a try-with-resources statement. Finally, for sorting you can store your words in a TreeSet in which the elements are ordered using their natural ordering2. Something like,
File file = new File("C:/", "Kennedy.txt");
try (Scanner scanner = new Scanner(file)) {
Set<String> words = new TreeSet<>();
int line_count = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
line_count++;
String[] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
Stream.of(tokens).forEach(word -> words.add(word));
}
System.out.printf("The file contains %d lines, and in alphabetical order [%s]%n",
line_count, words);
} catch (Exception e) {
e.printStackTrace();
}
1Mainly because it requires less code.
2or by a Comparator provided at set creation time
If you are storing the tokens in a String Array, use Arrays.sort() and get a naturally sorted Array. In this case as its String, you will get a sorted array of tokens.
try {
BufferedReader sc = new BufferedReader(new FileReader("/home/aravind/Desktop/India.txt"));
ArrayList<String> name = new ArrayList<>();
ArrayList<String> Location = new ArrayList<>();
ArrayList<String> Id = new ArrayList<>();
ArrayList<String> Details = new ArrayList<>();
String line = " ";
while ((line = sc.readLine()) != null) {
if (!line.trim().equals("")) {
System.out.println(line);
if (line.toLowerCase().contains("name")) {
name.add(line.split(":")[1].trim());
}
if (line.toLowerCase().contains("Location")) {
Location.add(line.split(":")[1].trim());
}
if (line.toLowerCase().contains("Id")) {
Id.add(line.split(":")[1].trim());
}
if (line.toLowerCase().contains("Details")) {
Details.add(line.split(":")[1].trim());
}
}
}
for (int i = 0; i < name.size(); i++) {
PrintWriter out = new PrintWriter(newFileWriter("output.csv"));
out.println("name;Location;Id;Details;");
out.println(name.get(i) + ";"
+ Location.get(i) + ";"
+ Id.get(i) + ";"
+ Details.get(i) + ";");
out.close();
}
sc.close();
} catch (Exception e) {
}
and my input file looks like
name = abc
id = 123
Place = xyz
Details = some texts with two line
name = aaa
id = 54657
Place = dfd
Details = some texts with some lines
What could be the problem why it is not printing in csv file instead prints o/p in console..Kindly help me
In your file, title and value are always separated by "=", whereas at runtime you trim strings by ":". You should replace ":" by "=", thus your trim result will not be empty at index 1.:
name.add(line.split("=")[1].trim());