I am having issues with reading a csv file and UTF-8. What I am doing is, reading the file to a String Array. Converting the String Array to a 2D String Array, depending on the line separator. Cleaning the line separator and displaying the 2D String Array in the console.
The issue is, that special characters like ö and ä are messed up on the console.
System.out.println("Default Charset=" + Charset.defaultCharset());
Tells me that my system is using UTF-8. What am I doing wrong?
I´m handling the CSV files with a 2D Array to get direct access to the rows and columns. Is there a better approach for that?
// Reading File
public static String[] readFile(String path) throws IOException {
FileReader input = new FileReader(path);
BufferedReader br = new BufferedReader(input);
String[] stringBuff = new String[countLines(path)];
int lines = countLines(path);
for (int j = 0; j < lines; j++) {
stringBuff[j] = br.readLine();
}
br.close();
return stringBuff;
}
// Converting to a 2D Array
public static String[][] convert(String[] array, String path) throws IOException {
int lines = countLines(path);
int[] locationarray;
int columns = (findcolumn(array)) + 1;
String[][] array2 = new String[lines][columns];
for (int i = 0; i < array.length; i++) {
locationarray = findlocation(array, i);
for (int j = 0; j < columns; j++) {
array2[i][j] = array[i].substring(locationarray[j], locationarray[j + 1]);
array2[i][j] = cleanup(array2[i][j]);
// System.out.print(array2[i][j]);
}
// System.out.println();
}
return array2;
}
// Show Array
public static void showarray(String[][] srcfinal) {
for (int i = 0; i < srcfinal.length; i++) {
for (int j = 0; j < srcfinal[i].length; j++) {
System.out.print(srcfinal[i][j]);
}
System.out.println();
}
}
Related
I am trying to convert a text file into a 2 dimensional character array. I am part of the way there but the last line of my array is not fully correct. Here's my code:
protected void readMap(String fileName) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(fileName));
char[] chars;
int lines=0;
while (br.readLine() != null) {
lines++;
}
File file = new File(fileName);
try (FileReader reader = new FileReader(file)) {
chars = new char[(int) file.length()];
reader.read(chars);
reader.close();
} catch (IOException e) {
}
int columns = ((int) file.length())/lines;
map = new char[lines][columns];
for(int i=0; i<lines;i++){
for(int j=0;j<columns;j++){
map[i][j] = chars[j%columns+i*columns];
}
}
for(int ro=0; ro<map.length; ro++){
for(int colum=0; colum<(map[0].length); colum++){
System.out.print(map[ro][colum]);
}
}
return null;
}
Here's the output:
##########################
#........................#
#.....###........###.....#
#......G..........G......#
#........................#
#...........E............#
#......G.........G.......#
#........G.....G.........#
#..........###...........#
#........................#
#################
^missing #'s here
I'm very confused on why this is occuring. I've tried changing how I print the array but i'm pretty sure its how its to do with how i've converted the 1d 'chars' array to the 2d 'map' array.
I'm really lost so any help would be much appreciated! Thank you.
I'm guessing your file looks something like this
##########################
#........................#
#.....###........###.....#
#......G..........G......#
#........................#
#...........E............#
#......G.........G.......#
#........G.....G.........#
#..........###...........#
#........................#
##########################
If you print the file length, you will see that the file length is 296
As Your code row = 11 and columns = 26
When you are copying to map you are copying up to 11 * 26 = 286
Try the UPDATED code below
public void readMap(String fileName) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(fileName));
int lines = 0, columns = 0;
String str;
List<String> lineList = new ArrayList<>();
while ((str = br.readLine()) != null && str.length() != 0) {
lines++;
columns = Math.max(columns, str.length()); // as it's not fixed
lineList.add(str);
}
System.out.println("Row : " + lines);
System.out.println("Columns : " + columns);
char[][] map = new char[lines][columns];
for (int i = 0; i < lines; i++) {
String currentLine = lineList.get(i);
int idx = 0;
for (int j = 0; j < currentLine.length(); j++) {
map[i][j] = currentLine.charAt(idx++);
}
}
for (int r = 0; r < map.length; r++) {
for (int c = 0; c < (map[0].length); c++) {
System.out.print(map[r][c]);
}
System.out.println();
}
}
I've just executed the code and the map prints as expected. The issue may be down to the file itself as that is the uncommon factor.
edit:
The results you have observed is because you may have a new line character, or other special character, at the end of or somewhere in the file. Removing this you should see the consistent map you want.
Alternative
protected static void readMap(String fileName) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line = "";
List<String> lines = new ArrayList<>();
while ((line = br.readLine()) != null) {
lines.add(line);
}
char[][] chars = new char[lines.size()][];
for (int col = 0; col < lines.size(); col++) {
for (int row = 0; row < lines.get(col).length(); row++) {
chars[col] = lines.get(col).toCharArray();
}
}
for (int col = 0; col < chars.length; col++) {
for (int row = 0; row < chars[col].length; row++) {
System.out.print(chars[col][row]);
}
System.out.println();
}
}//My rows and cols may be back to front
Few other notes:
You shouldn't be returning a value from a void method, even null (You'll want to return null if the return type is Void).
Your compiler may complain if you don't initialize chars initially, as mine did. char[] chars = null; would do it in this scenario.
I'm trying to read in a file of text, and "encrypt"/convert each letter to +1 from the ASCII table (I also want to "decrypt" so -1 for that). So "a" will become "b", "b" to "c" and so forth. I only need to convert alphabetic letters (Ignore everything else, print them as is). I'm having troubles with this part of the code:
for(int i = 0; i <= words.size(); i++)
{
for(int j = 0; j <= words.get(i).length(); j++)
{
char ch = ' ';
ch = words.get(i).charAt(j);
ch += 1;
morewords.add(ch);
}
fileOut.print(morewords.get(i) + " ");
}
I've figured out how to +1 the char, but I'm not sure how to add that back in to an array or print it out correctly (Since "morewords.add(ch)" is only going to add the char, instead of converting all the chars an adding a string). The "words.get(i).length()" takes the entire length of the array "words", when I just want the length of the string # position "i" in the array, so it throws an error since the length of the array is longer than the string word. I've been stuck on this for hours and I cannot figure it out. I'm thinking maybe I shouldn't read them in as strings and should have read them in as chars and this might have all been simpler?
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
ArrayList<String> words = new ArrayList<String>();
ArrayList<Character> morewords = new ArrayList<Character>();
String fileName = ""; //Replace Test with this
File f;
Scanner fileIn;
System.out.println("Please enter a file name for encryption: ");
//fileName = in.nextLine();
fileName = "Test.txt";
try
{
//Build the file and attach a scanner to it
f = new File (fileName);
fileIn = new Scanner (f);
System.out.println(f.exists()); //For errors
int counting = 0;
//Reads in indvidual strings.
for(counting =0; fileIn.hasNext(); counting++)
{
words.add(fileIn.next());
System.out.println(words);
}
PrintWriter fileOut = new PrintWriter ("Backwards.txt");
for(int i = 0; i <= words.size(); i++)
{
for(int j = 0; j <= words.get(i).length(); j++)
{
char ch = ' ';
ch = words.get(i).charAt(j);
ch += 1;
morewords.add(ch);
}
fileOut.print(morewords.get(i) + " ");
}
fileOut.close();
}
catch(FileNotFoundException e)
{
System.out.println("Couldn't find file");
}
}
First in a for loops is right to do
for (int i = 0; i <= words.size()-1; i++){}
if you'r starting at 0 you end at length-1
what i have changed is
PrintWriter fileOut = new PrintWriter("C:/Backwards.txt");
for (int i = 0; i <= words.size()-1; i++)
{
for (int j = 0; j <= words.get(i).length()-1; j++)
{
char ch = ' ';
ch = words.get(i).charAt(j);
ch ++; // +=1
morewords.add(ch);
fileOut.print(ch);
}
fileOut.print(" ");
}
fileOut.close();
and it output right if i have understood right =)
this is my code
public static void main(String[] args) throws Exception
{
BufferedReader inChannel = new BufferedReader(new FileReader("C:/script.txt"));
BufferedWriter outChannel = new BufferedWriter(new FileWriter("C:/output.txt"));
String toParse = "";
while ( (toParse = inChannel.readLine()) != null )
{
String toWrite = "";
for(int i=0; i!=toParse.length();i++)
{
char c = toParse.charAt(i);
if(true) //check if must be encoded or not
{
c++;
toWrite += c;
}
}
outChannel.write(toWrite);
outChannel.newLine();
}
inChannel.close();
outChannel.close();
}
hope helped
I'm trying to read a csv file into either an ArrayList or a String [][] array. In this I'm trying to read it into a list and then form the list, using a tokenizer, into an array. The csv file have 7 columns (A - G) and 961 rows (1-961). My for loop for the 2D array keeps returning a null pointer, but I think it should be working..
public class FoodFacts
{
private static BufferedReader textIn;
private static BufferedReader foodFacts;
static int numberOfLines = 0;
static String [][] foodArray;
public static String aFact;
static int NUM_COL = 7;
static int NUM_ROW = 961;
// Make a random number to pull a line
static Random r = new Random();
public static void main(String[] args)
{
try
{
textIn = new BufferedReader(new InputStreamReader(System.in));
foodFacts= new BufferedReader(new FileReader("foodfacts.csv"));
Scanner factFile = new Scanner(foodFacts);
List<String> facts = new ArrayList<String>();
String fact;
System.out.println("Please type in the food you wish to know about.");
String request = textIn.readLine();
while ( factFile.hasNextLine()){
fact = factFile.nextLine();
StringTokenizer st2 = new StringTokenizer(fact, ",");
//facts.add(fact);
numberOfLines++;
while (st2.hasMoreElements()){
for ( int j = 0; j < NUM_COL ; j++) {
for (int i = 0; i < NUM_ROW ; i++){
foodArray [j][i]= st2.nextToken(); //NULL POINTER HERE
System.out.println(foodArray[j][i]);
}
}
}
}
}
catch (IOException e)
{
System.out.println ("Error, problem reading text file!");
e.printStackTrace();
}
}
}
Initialize your foodArray as foodArray = new String[NUM_ROW][NUM_COL]; before using it.
Also, there is no need for inner for loop as you are reading one row at a time.
use numberOfLines as row:
while ( factFile.hasNextLine() && numberOfLines < NUM_ROW){
fact = input.nextLine();
StringTokenizer st2 = new StringTokenizer(fact, ",") ;
//facts.add(fact);
while (st2.hasMoreElements()){
for ( int j = 0; j < NUM_COL ; j++) {
foodArray [numberOfLines][j]= st2.nextToken();
System.out.println(foodArray[numberOfLines][i]);
}
}
numberOfLines++;
}
Alternatively, I think you can use split to get all columns as once e.g.
while ( factFile.hasNextLine() && numberOfLines < NUM_ROW){
fact = input.nextLine();
foodArray [numberOfLines++] = fact.split(",");
}
One question: Is there any specific purpose for declaring all variables as static class variables? Most of them fit as local variable inside the method e.g. numberOfLines?
You can use this String [][] foodArray = csvreadString(filename); method. It actually reads the file twice, but I don't know how to get the csv dimension without reading the data (you need the dimension in order to initialize the array), and this is very fast in comparison to other methods that I tried.
static public class PairInt {
int rows = 0;
int columns = 0;
}
static PairInt getCsvSize(String filename) throws Throwable {
PairInt csvSize = new PairInt();
BufferedReader reader = new BufferedReader(new FileReader(new File(filename)));
String line;
while ((line = reader.readLine()) != null) {
if (csvSize.columns == 0) {
csvSize.columns = line.split(",").length;
}
csvSize.rows++;
}
reader.close();
return csvSize;
}
static String[][] csvreadString(String filename) throws Throwable {
PairInt csvSize = getCsvSize(filename);
String[][] data = new String[csvSize.rows][csvSize.columns];
BufferedReader reader = new BufferedReader(new FileReader(new File(filename)));
for (int i = 0; i < csvSize.rows; i++) {
data[i] = reader.readLine().split(",");
}
return data;
}
I am kind of stuck. How do I get this to work or are there a better way? Please give code examples.
public char[][] charmap = new char[SomeInts.amount][SomeInts.amount];
public void loadMap() throws IOException{
BufferedReader in = new BufferedReader(new FileReader("map1.txt"));
String line = in.readLine();
while (line != null){
int y = 0;
for (int x = 0; x < line.length(); x++){
//Error
charmap[x][y] = line[x];
//
}
y++;
}
}
The syntax line[x] is reserved for arrays. A String is not an array. You could use the String#charAt method and write:
charmap[x][y] = line.charAt(x);
Use String.charAt(int) to fetch character from strings..
Try this.
char[][] mapdata = new char[SomeInts.amount][SomeInts.amount];
public void loadMap() throws IOException{
BufferedReader in = new BufferedReader(new FileReader("map1.txt"));
String line = in.readLine();
ArrayList<String> lines = new ArrayList<String>();
// Load all the lines
while (line != null){
lines.add(line);
}
// Parse the data
for (int i = 0; i < lines.size(); i++) {
for (int j = 0; j < lines.get(i).length(); j++) {
mapdata[j][i] = lines.get(i).charAt(j);
}
}
}
Hope this helps.
I need to read a list of numbers in a file and store it into a 2d array.
This is what I have so far. How would I go about achieving this goal?
//this is only part of my code
public class RainFall
{
double[][] precip;
public RainFall()
{
precip = new double [5][12];
}
public void readFile(BufferedReader infile) throws IOException
{
FileInputStream infile = new FileInputStream("numbers.dat");
BufferedReader br = new BufferedReader(new InputStreamReader(infile));
String[][] myarray = new String[5][12];
while (infile.readLine() != null)
{
for (int j = 0; j < 5; j++)
{
for (int i = 0; i < 12; i++)
{
myarray[j][i] = infile.readLine();
}
}
}
infile.close();
}
numbers.dat is 60 lines of:
1.01
0.03
2.14
0.47
//Is each number on a new line? You're very close, I added a few lines below.
public class RainFall
{
double[][] precip;
public RainFall()
{
precip = new double [5][12];
}
public void readFile(BufferedReader infile) throws IOException
{
//FileInputStream infile = new FileInputStream("numbers.dat");
BufferedReader br = new BufferedReader(new FileReader("numbers.dat"));
String line = "";
String[][] myarray = new String[5][12];
while ((line = br.readLine()) != null)
{
double num = Double.parseDouble(line.trim());
for (int j = 0; j < 5; j++)
{
for (int i = 0; i < 12; i++)
{
precip[j][i] = num;
}
}
}
br.close();
}
Instead of
String[][] myarray = new String[5][12];
use
double[][] myarray = new double[5][12];
Then sub this into the loop:
myarray[j][i] = Double.parseDouble(infile.readLine());