List of russian names from input txt file
Александр
Роман
Михаил
This code sorts these names correctly in IntelliJ Idea during debugging.
When I create a jar file and run it from the windows console java -jar E:\\sort-it.jar, then in the output file the first name is Роман, although it should be Александр, as in debugging.
The incorrect order from jar launch is
Роман
Александр
Михаил
The correct order is
Александр
Михаил
Роман
What could be the problem?
package programs;
import java.io.*;
import java.util.*;
public class Main{
public static String inputFileName = "E:/in.txt";
public static String outputFileName = "E:/out.txt";
public static List<String> FetchFileData(String fileName) throws IOException {
List<String> tempArray = new ArrayList();
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line;
while ((line = reader.readLine()) != null){
tempArray.add(line);
}
reader.close();
return tempArray;
}
public static List<String> SortWords(List<String> inputArray) {
String temp;
for (int i = 0; i < inputArray.size(); i++){
for (int j = i + 1; j < inputArray.size(); j++){
if (inputArray.get(i).compareTo(inputArray.get(j)) > 0){
temp = inputArray.get(i);
inputArray.set(i, inputArray.get(j));
inputArray.set(j, temp);
}
}
}
return inputArray;
}
public static void WriteToFile(List<String> inputArray, String fileName) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
for (int i = 0; i < inputArray.size(); i++) {
writer.write(inputArray.get(i));
writer.newLine();
}
writer.close();
}
public static void main(String[] args) throws IOException {
List<String> unsortedArray;
List<String> sortedArray;
unsortedArray = FetchFileData(inputFileName);
sortedArray = SortWords(unsortedArray);
WriteToFile(sortedArray, outputFileName);
}
}
A small problem is that FileReader uses the default platform encoding.
In the IDE & Windows that could be another that in the console.
Better do:
public static List<String> FetchFileData(String fileName) throws IOException {
Charset charset = Charset.forName("Cp1251");
return Files.readAllLines(Paths.get(fileName), charset);
}
Specifying the charset of your files ensures that the application is portable to other computers (with the same file). Files provides support for writing too.
Ensure that every line trimmed of spaces and maybe the Unicode BOM character, \uFEFF:
String line = lines.get(i);
line = line.trim().replace("\uFEFF", "");
That there are better solutions that compareTo has already been said.
No sneeky Latin lookalike letters were inserted instead of Cyrillic.
The code looks fine too.
So check the charset; something else I do not see, as unlikely as it is.
Related
For now in my program i am using hard-coded values, but i want it so that the user can use any text file and get the same result.
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.File;
public class a1_12177903
{
public static void main(String [] args) throws IOException
{
if (args[0] == null)
{
System.out.println("File not found");
}
else
{
File file = new File(args[0]);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line = "";
while (br.ready())
{
line += br.readLine();
}
String[] work = line.split(",");
double[] doubleArr = new double[work.length];
for (int i =0; i < doubleArr.length; i++)
{
doubleArr[i] = Double.parseDouble(work[i]);
}
double maxStartIndex=0;
double maxEndIndex=0;
double maxSum = 0;
double total = 0;
double maxStartIndexUntilNow = 0;
for (int currentIndex = 0; currentIndex < doubleArr.length; currentIndex++)
{
double eachArrayItem = doubleArr[currentIndex];
total += eachArrayItem;
if(total > maxSum)
{
maxSum = total;
maxStartIndex = maxStartIndexUntilNow;
maxEndIndex = currentIndex;
}
if (total < 0)
{
maxStartIndexUntilNow = currentIndex;
total = 0;
}
}
System.out.println("Max sum : "+ maxSum);
System.out.println("Max start index : "+ maxStartIndex);
System.out.println("Max end index : " +maxEndIndex);
}
}
}
I've fixed it so it takes in the name of the text file from the command line. if anyone has any ways to improve this, I'll happily accept any improvments.
You can do this with Java8 Streams, assuming each entry has it's own line
double[] doubleArr = Files.lines(pathToFile)
.mapToDouble(Double::valueOf)
.toArray();
If you were using this on production systems (rather than as an exercise) it would be worth while to create the Stream inside a Try with Resources block. This will make sure your input file is closed properly.
try(Stream<String> lines = Files.lines(path)){
doubleArr = stream.mapToDouble(Double::valueOf)
.toArray();
}
If you have a comma separated list, you will need to split them first and use a flatMap.
double[] doubleArr = Files.lines(pathToFile)
.flatMap(line->Stream.of(line.split(","))
.mapToDouble(Double::valueOf)
.toArray();
public static void main(String[] args) throws IOException {
String fileName = "";
File inputFile = new File(fileName);
BufferedReader br = new BufferedReader(new FileReader(inputFile));
// if input is in single line
StringTokenizer str = new StringTokenizer(br.readLine());
double[] intArr = new double[str.countTokens()];
for (int i = 0; i < str.countTokens(); i++) {
intArr[i] = Double.parseDouble(str.nextToken());
}
// if multiple lines in input file for a single case
String line = "";
ArrayList<Double> arryList = new ArrayList<>();
while ((line = br.readLine()) != null) {
// delimiter of your choice
for (String x : line.split(" ")) {
arryList.add(Double.parseDouble(x));
}
}
// convert arraylist to array or maybe process arrayList
}
This link may help: How to use BufferedReader. Then you will get a String containing the array.
Next you have several ways to analyze the string into an array.
Use JSONArray to parse it. For further information, search google for JSON.
Use the function split() to parse string to array. See below.
Code for way 2:
String line="10,20,50";//in fact you get this from file input.
String[] raw=line.split(",");
String[] arr=new String[raw.length];
for(int i=0;i<raw.length;++i)arr[i]=raw[i];
//now arr is what you want
Use streams if you are on JDK8. And please take care of design principles/patterns as well. It seems like a strategy/template design pattern can be applied here. I know, nobody here would ask you to focus on design guidelines.And also please take care of naming conventions. "File" as class name is not a good name.
I have three programs to write for my Object Oriented Programming course, all involving file input/output, each of which contain no compile errors, yet they do not do what they are supposed to in run time (they don't print to the outFile like they're supposed to).
I know that the input file is being read and saved in the correct location, because Eclipse would indicate if either of these was not the case.
Furthermore, I have not (to my knowledge) committed any of the common errors involving not including throws exceptions of closing the read/write files.
I am attaching the first of my i/o assignments here with the hopes that the other files have similar errors that I can fix as soon as I can figure out what's wrong with this one.
import java.io.*;
public class GreenK4_Lab8 {
public static void main(String[] args) throws IOException {
int[] numbers = new int[countLines()];
int i = 0;
for(i = 0; i < numbers.length; i++) {
numbers[i] = readValues(i);
}
printOdd(numbers);
}
public static int countLines() throws IOException {
BufferedReader inFile = new BufferedReader(
new FileReader( "Lab8_TestFile.txt" ) );
int lineNumber = 1;
String nextLine = inFile.readLine();
while( nextLine != null ) {
lineNumber ++;
}
inFile.close();
return lineNumber;
}
public static int readValues(int number) throws IOException {
BufferedReader inFile = new BufferedReader(
new FileReader( "Lab8_TestFile.txt" ) );
int value = 0;
for(int i = 0; i < number; i++) {
String nextLine = inFile.readLine();
value = Integer.parseInt( nextLine );
}
inFile.close();
return value;
}
public static void printOdd(int[] array) throws IOException {
PrintWriter outFile = new PrintWriter( "results.out" );
for(int i = 0; i < array.length; i++) {
int value = array[i];
if( value % 2 != 0)
outFile.println( value );
}
outFile.close();
}
}
The following are the contents of the Lab8_TestFile.txt
4
6
2
10
8
1
-1
-2147483648
2147483647
5
9
3
7
-7
As other commenters pointed out, change your code in countLines function from
String nextLine = inFile.readLine();
while( nextLine != null ) {
lineNumber ++;
}
to
while (inFile.readLine() != null) {
lineNumber ++;
}
With this change your program works as expected.
There are multiple things wrong with your code. Let´s start from the beginning: your countLines method does not work as intended and will create a infinite loop because your while-condition will never be evaluated to false (unless your file is empty):
// String nextLine = inFile.readLine();
// while(nextLine != null) {
while (inFile.readLine() != null) {
lineNumber++;
}
You may want to check Number of lines in a file in Java for a faster and better performing version of retrieving the line count of a file.
Additionally your readValues function opens the file for every line it wants to read, reads the file until that line and closes the file again -> BAD. What you should do instead is the following:
public static void readValues(int[] contentsOfFile) throws IOException {
BufferedReader inFile = new BufferedReader(new FileReader("Lab8_TestFile.txt"));
for(int i = 0; i < contentsOfFile.length; i++) {
String nextLine = inFile.readLine();
contentsOfFile[i] = Integer.parseInt( nextLine );
}
inFile.close();
}
However that is not pretty as well since you rely on a adequately sized int array to be passed in. If you still want to get the line count separately from reading the values, do so, but let the readValues handle the appropriate reading by itself. That could result in something like:
public static ArrayList<Integer> readValues() throws IOException {
BufferedReader inFile = new BufferedReader(new FileReader("Lab8_TestFile.txt"));
ArrayList<Integer> integerContents = new ArrayList<>();
String nextLine = null;
while ((nextLine = inFile.readLine()) != null) {
integerContents.add(Integer.parseInt(nextLine));
}
inFile.close();
return integerContents;
}
That way you parse the file only once for reading the values. If you need to get a int[] back, take a look at How to convert an ArrayList containing Integers to primitive int array? to get an idea on how to extract that from the given data structure.
Your main function might result in something like:
public static void main(String[] args) throws IOException {
int numberOfLines = countLines(); // technically no longer needed.
int[] intContents = convertIntegers(readValues());
printOdd(intContents);
}
I want to interchange the last 2 words in a java file.
The file is called text_d.txt and it contains:
Student learns programming java.
and this is the code(below).The output is the same and I don't understand why it does not change.
import java.nio.*;
import java.io.*;
import java.lang.*;
public class Test3 {
public static void main(String[] args) throws Exception {
String s2="text_t.txt";
File _newf = new File("text_d.txt");
changeOrder(_newf);
}
public static void changeOrder(File f) throws Exception {
FileInputStream _inp=new FileInputStream(f.getAbsolutePath());
BufferedReader _rd=new BufferedReader(new InputStreamReader(_inp));
String _p=_rd.readLine();
while (_p != null) {
String [] _b = _p.split(" ");
for(int i = 0; i <= _b.length; i++) {
if(i == 2) {
String aux=_b[i];
_b[i]=_b[i+1];
_b[i+1]=aux;
break;
}
}
_p=_rd.readLine();
}
}
}
For reading, interchanging and writing the file, I suggest you to do something like this:
public class Test3 {
public static void main(String[] args) throws Exception {
String s2="text_t.txt";
File _newf = new File("text_d.txt");
changeOrder(_newf);
}
public static void changeOrder(File f) throws Exception {
FileInputStream _inp = new FileInputStream(f.getAbsolutePath());
BufferedReader _rd = new BufferedReader(new InputStreamReader(_inp));
ArrayList<String[]> newFileContent = new ArrayList<String[]>();
String _p=_rd.readLine();
while (_p != null) {
String [] _b = _p.split(" ");
String temp = _b[_b.length - 2];
_b[_b.length - 2] = _b[_b.length - 1];
_b[_b.length - 1] = temp;
newFileContent.add(_b);
_p=_rd.readLine();
}
PrintWriter writer = new PrintWriter(f.getAbsolutePath(), "UTF-8");
for (String[] line : newFileContent) {
for (String word : line) {
writer.print(word);
}
writer.println();
}
writer.close();
}
There is two minor changes:
First I changed the for loop you used in your code, with 3 lines of code.
Second I used to add all of lines which changed in the while loop in an ArrayList of String arrays which could hold changes in order to save on the file in the future.
And after all, I used an instance of PrintWriter class which could write a file on the hard disk. and in a foreach loop, I wrote contents of new file on the input file.
You could try something like this:
public static void changeOrder(File f) throws Exception {
FileInputStream _inp = new FileInputStream(f.getAbsolutePath());
BufferedReader _rd = new BufferedReader(new InputStreamReader(_inp));
String _p = _rd.readLine();
while (_p != null) {
String [] _b=_p.split(" ");
String temp = _b[_b.length - 1];
_b[_b.length - 1] = _b[_b.length - 2];
_b[_b.length - 2] = temp;
_p = _rd.readLine();
}
}
But if you want the file to be updated you need to write the results to the file...You should use something to write to the file like a PrintWriter.
This should do the trick You want:
public static String changeOrder(File fileName) throws IOException {
Scanner file = new Scanner(fileName);
String line = file.nextLine();
line = line.replace('.', ' ');
String[] items = line.split(" ");
StringBuilder sb = new StringBuilder();
sb.append(items[0] + " ");
sb.append(items[1] + " ");
sb.append(items[3] + " ");
sb.append(items[2] + ".");
return sb.toString();
}
Expected result: Student learns java programming.
Hey so I've written some code to read the contents of a text file, do some comparisons and output either 1 or 0 into a 2D array. Here is a snippet
import java.io.*;
import java.util.*;
public class readFile
{
private String path;
//declare variables for visited and link
//String inputSearch1 = "Visited";
//String inputSearch2 = "Link";
String word;
public readFile(String pathname)
{
path = pathname;
}
//open the file and read it and search each line of the file for 'Visited' and 'Link'
public String[] OpenFile() throws IOException
{
FileReader fr = new FileReader(path);
BufferedReader lineReader = new BufferedReader(fr);
int numberOfLines = readLines();
String[] lineData = new String[numberOfLines];
int i;
for(i=0; i<numberOfLines; i++)
{
lineData[i] = lineReader.readLine();
}
lineReader.close();
return lineData;
}
//allows the file to be parsed without knowing the exact number of lines in it
int readLines() throws IOException
{
FileReader file_to_read = new FileReader(path);
BufferedReader bf = new BufferedReader(file_to_read);
String aLine;
int numberOfLines = 0;
while((aLine = bf.readLine()) != null)
{
numberOfLines++;
}
bf.close();
return numberOfLines;
}
int outLinks;
int inLinks;
String bLine;
String[] searchStrings() throws IOException
{
FileReader ftr = new FileReader(path);
BufferedReader bf2 = new BufferedReader(ftr);
int numberOfLines = readLines();
//String bLine;
String[] parseLine = new String[numberOfLines]; //array to store lines of text file
int[][] linkMatrix = new int[outLinks][inLinks]; //2d array to store the outLinks and inLinks
int i;
for(i=0; i<numberOfLines; i++)
{
parseLine[i] = bf2.readLine();
int j, k;
for(j=0; j<outLinks; j++)
{
for(k=0; k<inLinks;k++)
{
if(bLine.startsWith("Visited") && equals(bLine.startsWith("Link")))
{
linkMatrix[outLinks][inLinks] = 1;
}
else
{
linkMatrix[outLinks][inLinks] = 0;
}System.out.println(Arrays.deepToString(linkMatrix));
}//System.out.println();
}
}bf2.close();
return parseLine;
}
I am now trying to output this from the main method but each time I run it, all I get is the contents of the text file and no 2D matrix.
import java.io.IOException;
public class linkStatistics
{
public static void main(String[] args) throws IOException
{
// TODO Auto-generated method stub
//read file
String fileName = "C:\\Users\\Ikemesit\\Documents\\Lab_4.txt";
try
{
readFile file = new readFile(fileName);
//String[] lines = file.OpenFile();
String[] lines = file.searchStrings();
int i;
for(i=0;i<lines.length;i++)
{
System.out.println(lines[i]);
//System.out.println(lines2[i]);
}
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
}
Any help would be much appreciated! Thanks.
This condition has many problems :
if(bLine.startsWith("Visited") && equals(bLine.startsWith("Link")))
You never initialize bLine. This means that the condition would throws NullPointerException. I'm assuming you want to test the lines you read from the file instead.
equals makes no sense in this context - it compares your readFile instance with a boolean.
A line can't start with both prefixes, so you probably want || (OR) instead of && (AND).
I think this would make more sense :
if(parseLine[i].startsWith("Visited") || parseLine[i].startsWith("Link"))
I am learning Java and in order to learn more about Java IO I am making a program to read a file path and return an array that contains everything from the file. I didn't want to specify that the data had to be integers so I've been working in strings. I'm running into an issue when I try to run a method returning an array. Is there a better way I should be writing this code?
import java.io.*;
public class OrganizeIO
{
public static void main(String[] args) throws Exception
{
String sampleData[] = readFile("C://Users/Tweak/workspace/FileIO/resources/data.txt");
int i = 0;
while(sampleData[i] != null)
{
System.out.print(sampleData[i]);
i++;
}
}
public static String[] readFile(String file) throws IOException
{
BufferedReader br = null;
String currentLine;
String[] data;
br = new BufferedReader(new FileReader(file));
int i = 0;
while((currentLine = br.readLine()) != null)
{
System.out.println(currentLine);
currentLine = data[i];
i++;
}
return data[];
}
}
You're not storing anything in data, not to mention you haven't even initialized it (which results in a compilation error). You should be using a List anyway, since you don't know how many lines you are going to read beforehand:
List<String> data = new ArrayList<String>();
while ((currentLine = br.readLine()) != null) {
data.add(currentLine);
}
return data.toArray(new String[data.size()]); // or just return the list?
Also, don't forget to close your BufferedReader:
br.close();
Well for one it looks like you while loop should be
while((currentLine = br.readLine()) != null)
{
System.out.println(currentLine);
data[i] = currentLine;
i++;
}
because you are returning nothing
I think you can work with the class Scanner to read the file and store it in a List.
// Open the file
Scanner scanner = new Scanner(new File("C:\\Users\\Tweak\\workspace\\FileIO\\resources\\data.txt"));
// Read the file line by line
List<String> result = new ArrayList<String>();
while (scanner.hasNext())
{
result.add(scanner.nextLine());
}
scanner.close();
// If you want an array
String sampleData[] = result.toArray(new String[result.size()]);
Since you don't know how many lines you get, storing the read lines directly in an array is inappropriate, better take a List implementation for that:
public static List<String> readFile (File file, String encoding) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding));
List<String> result = new LinkedList<String>();
String line;
while ((line = reader.readLine()) != null) {
result.add(line);
}
return result;
}
Usage:
public static void main (String[] args) throws IOException {
File file = new File("C://Users/Tweak/workspace/FileIO/resources/data.txt");
List<String> lines = readFile(file, "UTF-8");
for (String line : lines) {
System.out.println(line);
}
}
You can of course convert the List into a String array later, if that's what you want:
String[] linesArray = lines.toArray(new String[0]);