I am trying to figure out how to loop a filename. I have 10 files
each file is called Myfile01.txt , Myfile02.txt, Myfile03.txt all the way to Myfile10.txt
I did something like this for the first file name , it is in java.
String bob = new String("C:\\bob\\Myfile01.txt");
File file = new File(bob);
Scanner myinput = new Scanner(file);
Each file contains around 200 lines of data which i am storing in an array and using .hasnext to target what data goes into what array. each name is seperated with a line.
for (int i=0;i<=200;i++)
{
rank[i] = input.next();
firstname[i] =input.next();
lastname[i] = input.next();
dadname[i] = input.next();
momname[i] = input.next();
}
now when i finish storing everything in the text file I am looking for a way to go to the next txt document with a loop to avoid clunkiness. I can hardcode it but it would not be good style.
Thanks for any suggestions!
A loop and String.format should give you what you need:
for (int i = 1; i <= 10; i++) {
String bob = String.format("C:\\bob\\Myfile%02d.txt", Integer.valueOf(i));
// ...
}
The format pattern %02d pads an integer with a zero given that it is less than two digits in length, as defined in the syntax for string formatting.
If you want to walk through subdirectories you may also try:
try {
Files.walk(Paths.get(directory)).filter(f -> Pattern.matches("myFile\\d{2}\\.txt", f.toFile().getName())).forEach(f -> {
System.out.println("WHAT YOU WANT TO DO WITH f");
});
} catch (IOException e) {
e.printStackTrace();
}
Related
So I want to create a constructor that reads in a line of a file from a csv and save the first token into a variable and the remaining tokens into an array. This constructor will be used in a gradebook application but being new to txt/file manipulation I'm having a hard time.
A line will look like:
Billy Bob,68,79,95,83
I want to separate the tokens into these:
name = Billy Bob
grades[] = "68,79,95,83"
here is the code I have so far:
import java.io.*;
public class gradeBook {
public static void main(String[] args){
System.out.println("Java Grade Book version 1.0");
int lineCounter = 0;
String array[];
try{
File data = new File("/file/path/that/works");
InputStream f = new FileInputStream(data);
BufferedReader br = new BufferedReader(new InputStreamReader(f));
for (String line = br.readLine(); line != null; line = br.readLine()) {
System.out.println(line); // just here to check that the code is working thus far
//insert code here
//name should equal first token (which is two names like Billy Bob)
//grades[] should contain the other double type tokens (e.g. 56,87,89,90)
}
br.close();
}
catch(Exception e){
System.err.println("Error: File Couldn't Be Read");
}
}
}
And I want to loop through the file to get as many students as are on the file stored so I can manipulate the grades for averages among other things. This is a personal project to help improve my developing skills so any help, useful tutorial links, and tips will be greatly appreciated. But please don't suggest simplistic examples like the many tutorials I have already read that only use one data type.
Thanks for any help!
Split the line into an array;
String[] input = line.split(",");
String variable = input[0];
int[] grades= new int[input.lenght - 2];
for(int i = 1; i < input.length; i++)
{
grades[i] = input[i];// you might have to do Integer.pareseInt(input[i]);
}
I did not write this in an IDE, but the logic should be correct.
You are going to run into a new problem. You grade book will only contain the last entry. Try using a 2D array for grades and 1D array for names; I personally would not use arrays. I would use arraylist.
So I haven't tested computing my tokens with methods or anything else yet but I have tokenized the line to sum (ha ha oops, meant some) degree with this bit of code:
String[] tokens = line.split(",");
String name = tokens[0];
String grade1 = tokens[1];
String grade2 = tokens[2];
String grade3 = tokens[3];
String grade4 = tokens[4];
My task is to read a text file in chunks of 64 characters, and use 2 different processes called Substitution and Column Transposition to encrypt it. Then, I have to decrypt it and write it out to another file.
I have written and tested out both processes of encrypting and decrypting and it worked wonderfully. But then I tried to loop the processes in case more than 64 characters were in the input file.
As a test case, I tried a 128 character input file. Unfortunately, the result only gives me the first 64 characters twice. I've tracked the scanner position and it goes beyond 64, but the characters read start back from 0. I'm not sure what the problem is.
Here is the relevant part of my code:
public static void main(String[] args) {
//Declare variables
Scanner console = new Scanner(System.in);
String inputFileName = null;
File inputFile = null;
Scanner in = null;
do
{
//Check if there are enough arguments
try
{
inputFileName = args[1];
}
catch (IndexOutOfBoundsException exception)
{
System.out.println("Not enough arguments.");
System.exit(1);
}
catch (Exception exception)
{
System.out.println("There was an error. Please try again.");
System.exit(1);
}
//Check if Input File is valid
try
{
inputFile = new File(inputFileName);
in = new Scanner(inputFile);
outputFile = new File(outputFileName);
out = new Scanner(outputFile);
}
catch (FileNotFoundException exception)
{
System.out.println("Could not find input file.");
System.exit(1);
}
catch (Exception exception)
{
System.out.println("There was an error. Please try again.");
System.exit(1);
}
} while (outputFileName != null && !inputFile.exists());
//Encryption
//Prepare patterns
String subPattern = CreateSubstitutionPattern(hash);
int[] transPattern = CreateTranspositionPattern(hash);
//Apply patterns
String textContent = "";
String applySub = "";
String applyTrans = "";
do
{
textContent = Read64Chars(in);
applySub = applySub + ApplySubstitutionPattern(textContent, subPattern);
applyTrans = applyTrans + ApplyTranspositionPattern(applySub, transPattern);
} while (in.hasNext());
//Decryption
String encryptContent = "";
Scanner encrypt = new Scanner(applyTrans);
String removeTrans = "";
String removeSub = "";
do
{
encryptContent = Read64Chars(encrypt);
System.out.println(applyTrans);
removeTrans = removeTrans + RemoveTranspositionPattern(encryptContent, transPattern);
removeSub = removeSub + RemoveSubstitutionPattern(removeTrans, subPattern);
} while (encrypt.hasNext());
console.close();
in.close();
encrypt.close();
System.out.println(removeSub); //For temporary testing
}
public static String Read64Chars (Scanner in)
{
String textContent = "";
in.useDelimiter("");
for (int x=0; x<64; x++)
{
if (in.hasNext())
{
textContent = textContent + in.next().charAt(0);
}
}
return textContent;
}
Do note that I have more variables to fill in args[0] and args[2] but I removed them for simplicity.
I would like to know if it is true that once a scanner reads a portion of it's input, it "consumes" it, and that portion gets removed. Does the scanner reset itself when declared again through a method? For example, does the declaration only point to the input source of the original scanner, or the actual scanner with its current properties?
encrypt is a diffrent Scanner from in, which you advance by 64 characters when you first call Read64Chars. So, encrypt starts at the first character when you call Read64Chars(encrypt). It seems like you want to use the same Scanner both times.
Also, in the future please name your functions starting with a lowercase letter. I felt dirty typing that... :)
A proper solution to get the whole encrypted text would be a code like this
public static String encryptedTextFile (Scanner in)
{
//ArrayList<String> stringBlocksOf64Chars = new ArrayList<String>();
StringBuilder encryptedTxt = new StringBuilder();
String currentTxt = "";
while (in.hasNextLine()) {
String line = currentTxt + in.nextLine();
currentTxt = "";
int i = 0;
for( ; i < line.length()/64 ; i++){
currentTxt = line.substring(i * 64, (i+1)*64);
//TODO - encrypt the text before adding it to the list
encryptedTxt.append(currentTxt);//encryptedTxt.append(encrypt(currentTxt));
}
currentTxt = line.substring(i * 64, line.length());
}
encryptedTxt.append(currentTxt);
/*for(String str : stringBlocksOf64Chars)
System.out.println(str);*/
return encryptedTxt.toString();
}
Your loop for (int x=0; x<64; x++) makes sure that you read only first 64 characters always and not the complete file. To get around that you should actually read whole file line by line.
The above code block follows this idea.
Steps to break down the logic.
Read the file line by line using scanner.
Break each line into chunks of 64 characters and encrypt the block 64 characters at a time
Generate encrypted text adding the encrypted 64 characters.
Whatever you do first break down the logic/steps you want to use in your code to make it simpler to understand or code.
Break the lines into 64 characters
I got this assignment for school and all my other methods are working just fine, but reading unique words just doesn't work for me.
My method for reading txtfile:
public void lesBok(String filnavn) throws Exception {
File file = new File(filnavn);
Scanner innlestfil = new Scanner(file);
while (innlestfil.hasNextLine()) {
String s = innlestfil.nextLine();
if((ord.contains(s))){
for(i = 0; i < ord.size(); i++){
if(ord.get(i).toString().equalsIgnoreCase(s)){
ord.get(i).oekAntall();
}
}
}else{
Ord nyttOrd = new Ord(s);
ord.add(nyttOrd);
}
}
}
It reads the txt file, but the problem is that it doesn't difference from unique words.
So if a txt file is for example
hey
My
name
is
hey
It reads 5 words instead of 4.
When the same word pops up, I want it to run this method:
public void oekAntall(){
antall ++;
If you are not specifically required to read it in one word at a time, why not read the entire line and then parse it? I would recommend the StringTokenizer class to accomplish this. I'll write out some pseudo code to show what I mean.
String inputLine = sc.readLine();
StringTokenizer st = new StringTokenizer(inputLine, " "); //parse on spaces
while(st.hasMoreTokens()) {
//Parse tokens
array[x] = st.nextToken();
}
I've a txt file having over thousand line of text that has some integers at the starting.
Like:
22Ahmedabad, AES Institute of Computer Studies
526Ahmedabad, Indian Institute of Managment
561Ahmedabad, Indus Institute of Technology & Engineering
745Ahmedabad, Lalbhai Dalpatbhai College of Engineering
I want to store all the lines in another file without the integers.
The code I've written is:
while (s.hasNextLine()){
String sentence=s.nextLine();
int l=sentence.length();
c++;
try{//printing P
FileOutputStream ffs = new FileOutputStream ("ps.txt",true);
PrintStream p = new PrintStream ( ffs );
for (int i=0;i<l;i++){
if ((int)sentence.charAt(i)<=48 && (int)sentence.charAt(i)>=57){
p.print(sentence.charAt(i));
}
}
p.close();
}
catch(Exception e){}
}
But it outputs a blank file.
There are a couple of things in your code that should be improved:
Don't re-open the output file with every line. Just keep it open the whole time.
You are removing all numbers, not just numbers at the beginning - is that your intention?
Do you know any number that is both <= 48 and >= 57 at the same time?
Scanner.nextLine() does not include line returns, so you'll need a call to p.println() after every line.
Try this:
// open the file once
FileOutputStream ffs = new FileOutputStream ("ps.txt");
PrintStream p = new PrintStream ( ffs );
while (s.hasNextLine()){
String sentence=s.nextLine();
int l=sentence.length();
c++;
try{//printing P
for (int i=0;i<l;i++){
// check "< 48 || > 57", which is non-numeric range
if ((int)sentence.charAt(i)<48 || (int)sentence.charAt(i)>57){
p.print(sentence.charAt(i));
}
}
// move to next line in output file
p.println();
}
catch(Exception e){}
}
p.close();
You can apply this regular expression to each line that you read from the file:
String str = ... // read the next line from the file
str = str.replaceAll("^[0-9]+", "");
The regular expression ^[0-9]+ matches any number of digits at the beginning of the line. replaceAll method replaces the match with an empty string.
On top of mellamokb comments, you should avoid "magic numbers". There's no guarantee that that the digits will fall within the expected range of ASCII codes.
You can simply detect if a character is a digit using Character.isDigit
String value = "22Ahmedabad, AES Institute of Computer Studies";
int index = 0;
while (Character.isDigit(value.charAt(index))) {
index++;
}
if (index < value.length()) {
System.out.println(value.substring(index));
} else {
System.out.println("Nothing but numbers here");
}
(Nb dasblinkenlight has posted some excellent regular expression, which would probably easier to use, but if you're like, regexp turns my brain inside out :P)
I'm trying to make an array of strings using a list of names coming from a txt file.
So for example: If I have string[] names = {all the names from the txtfile(one name perline)}
I want to pass "names" into a method that takes in a array like "names"(the one I made above). The method will then run the names through another for loop and create a linked list. I'm really confusing myself on this and tried number of things but nothing seems to work. Right now It'll print out the first name correctly but every name after that just says null. So I have about 70 nulls being printed out.
public static void main(String[] args) {
//String[] names = {"Billy Joe", "Alan Bowe", "Sally Mae", "Joe Blow", "Tasha Blue", "Malcom Floyd"}; // Trying to print theses names..Possibly in alphabetical order
BigNode x = new BigNode();
Scanner in = new Scanner(System.in);
System.out.println("Enter File Name: ");
String Finame = in.nextLine();
System.out.println("You Entered " + Finame);
try {File file = new File(Finame);
BufferedReader readers = new BufferedReader(new FileReader(file));
// String nameLine = ;
String[] name;
name = new String[73];
String[] nameTO;
String nameLine;
// while ((nameLine = readers.readLine()) != null) {
for (int i = 0; i < name.length; i++){
name[i] = readers.readLine();
x.populateNodes(name);
} //}
} catch(IOException e) {
}
Why is x.populateNodes(name) inside the loop? Wouldn't you be populating it after filling your array?
Since I've no idea what BigNode is, I assume it should be one of the following
x.populateNodes(name[i]) inside the loop or x.populateNodes(name) outside the loop.