C# - Comparing/Replacing Text Using Two .txt Files - c#
I want to take in a certain format of one text file. After the first file is loaded and reformatted, I want to open a second text file and check if the second file has any text matches with the first re-formatted file. Right now I am successfully reformatting the first text file to how I want it. The first (reformatted) text file looks like this:
1 0010 12345 DEF, DEF-0320
1 0020 ABC-00010G ABC-A,1xx,10%,x1x,0603
1 0020A ABC-00010G ABC-A,1xx,10%,x1x,0603
1 0030A ABC-00127G ABC,4.7xx,10%,x1x,0805
.
.
.
I want to know how to take this file (above) and find the second column (0010, 0020, 0020A, 0030A, ...) and compare it/search for it in a second text file. The format for the second text file will look something like this:
10 BARE PCB
20 T C40, C3112
B D5, D45, D48
30 B R25
.
.
.
Once I am able to find the match from the first file (0010, 0020, 0020A, 0030A) with the second file (10, 20, B, 30) I want to grab the lines after the 10, 20, B, 30 and replace the first files 0010, 0020, 0020A, 0030A with them. Also, if the number from the first one does not end with an "A" (ie, 0010) I want to put a "T" at the end of the new file. However, if it does end with an "A" (ie, 0030A) I want to put a "B" at the end of the file. Also, for every value in the second file that is in the format "C40" (or similar) I want to place on a new line if there is multiple (seperated by a ",") and copy the same information from the above line. This meaning it would look like this:
1 AAAA BCD 12345 DEF, DEF-0320 T
1 C40 ABC-00010G ABC-A,1xx,10%,x1x,0603 T
1 C3112 ABC-00010G ABC-A,1xx,10%,x1x,0603 T
1 D5 ABC-00010G ABC-A,1xx,20%,x1x,0603 B
1 D45 ABC-00010G ABC-A,1xx,20%,x1x,0603 B
1 D48 ABC-00010G ABC-A,1xx,20%,x1x,0603 B
1 R25 ABC-00127G ABC,4.7xx,100%,x1x,0805 B
General basis of my code:
Open button: Opens a txt file.
Save button: Saves the new formatted text file where ever I want to save it to.
Clear button: Clears the text in all of the rich text boxes I use.
OpenRefs button: Opens the second txt file used to compare with the first file.**
**I am also trying to get this button to output the final formatting of the text into the final rich text box.
Here is my current code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace Formatter
{
public partial class Form : Form
{
// Create a OpenFileDialog to request a path and file name to open.
OpenFileDialog openFile = new OpenFileDialog();
OpenFileDialog openRefs = new OpenFileDialog();
public Form()
{
InitializeComponent();
}
private void openButton_Click(object sender, EventArgs e)
{
// Initialize the OpenFileDialog to specify the .txt extension as well as
// its intial directory for the file.
openFile.DefaultExt = "*.txt";
openFile.Filter = ".txt Files|*.txt";
openFile.InitialDirectory = "C:\\";
openFile.RestoreDirectory = true;
try
{
// Open the contents of the file into the originalTextRichTextBox.
if (openFile.ShowDialog() == DialogResult.OK && openFile.FileName.Length > 0)
originalTextRichTextBox.LoadFile(openFile.FileName, RichTextBoxStreamType.PlainText);
// Throws a FileNotFoundException otherwise.
else
throw new FileNotFoundException();
// Resets the formattedTextRichTextBox so multiple files aren't loaded on top of eachother.
formattedTextRichTextBox.ResetText();
foreach (string line in File.ReadAllLines(openFile.FileName))
{
// Uses regular expressions to find a line that has, digit(s), space(s), digit(s) + letter(s),
// space(s), digit(s), space(s), any character (up to 25 times).
Match theMatch = Regex.Match(line, #"^[\.*\d]+\s+[\d\w]+\s+[\d\-\w*]+\s+.{25}");
if (theMatch.Success)
{
// Stores the matched value in string output.
string output = theMatch.Value;
// Sets the formattedTextRichTextBox to the string output.
formattedTextRichTextBox.AppendText(output);
formattedTextRichTextBox.AppendText("\n");
}
}
}
// Catches an exception if the file was not opened.
catch (Exception)
{
MessageBox.Show("There was not a specified file path.", "Path Not Found Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void saveButton_Click(object sender, EventArgs e)
{
// Create a SaveFileDialog to request a path and file name to save.
SaveFileDialog saveFile = new SaveFileDialog();
// Initialize the SaveFileDialog to specify the .txt extension for the file.
saveFile.DefaultExt = "*.txt";
saveFile.Filter = ".txt Files|*.txt";
saveFile.InitialDirectory = "C:\\";
saveFile.RestoreDirectory = true;
try
{
// Save the contents of the formattedTextRichTextBox into the file.
if (saveFile.ShowDialog() == DialogResult.OK && saveFile.FileName.Length > 0)
formattedTextRichTextBox.SaveFile(saveFile.FileName, RichTextBoxStreamType.PlainText);
// Throws a FileNotFoundException otherwise.
else
throw new FileNotFoundException();
}
// Catches an exception if the file was not saved.
catch (Exception)
{
MessageBox.Show("There was not a specified file path.", "Path Not Found Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void clearButton_Click(object sender, EventArgs e)
{
try
{
// Resets the text in all of the boxes.
originalTextRichTextBox.ResetText();
formattedTextRichTextBox.ResetText();
refsTextRichTextBox.ResetText();
finalTextRichTextBox.ResetText();
}
// Catches an exception if the either text box could not be cleared.
catch (Exception)
{
MessageBox.Show("Could not clear the text.", "Clearing Text Box Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void openRefsButton_Click(object sender, EventArgs e)
{
// Initialize the OpenFileDialog to specify the .txt extension as well as
// its intial directory for the file.
openRefs.DefaultExt = "*.txt";
openRefs.Filter = ".txt Files|*.txt";
openRefs.InitialDirectory = "C:\\";
openRefs.RestoreDirectory = true;
try
{
// Open the contents of the file into the originalTextRichTextBox.
if (openRefs.ShowDialog() == DialogResult.OK && openRefs.FileName.Length > 0)
refsTextRichTextBox.LoadFile(openRefs.FileName, RichTextBoxStreamType.PlainText);
// Throws a FileNotFoundException otherwise.
else
throw new FileNotFoundException();
// ********************************************
// ********************************************
// ********************************************
// FROM HERE DOWN IS WHERE I NEED THE HELP! :)
// ********************************************
// ********************************************
// ********************************************
string[] refLines = System.IO.File.ReadAllLines(openRefs.FileName);
foreach (string line in refLines)
{
finalTextRichTextBox.AppendText(line + "\n");
}
try
{
using (StreamReader readRefs = new StreamReader(openRefs.FileName))
{
originalTextRichTextBox.ResetText();
List<string> refFileLines = new List<string>();
while (!readRefs.EndOfStream)
{
refFileLines.Add(readRefs.ReadLine());
}
using (StreamReader readFile = new StreamReader(openFile.FileName))
{
List<string> fileLines = new List<string>();
while (!readFile.EndOfStream)
{
fileLines.Add(readFile.ReadLine());
}
}
refFileLines.Contains("");
}
}
catch (Exception)
{
MessageBox.Show("Could not read file.", "Read File Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
// Catches an exception if the file was not opened.
catch (Exception)
{
MessageBox.Show("There was not a specified file path.", "Path Not Found Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
}
I am getting a little lost on what to do. I was trying to take in each line and store it in a list of strings and once I had both files (open button and openrefs button) read into two sets of List I was going to use string.contains("some_string") but in the files the numbers could each time I open a different file. I am not sure how I would go about iterating properly though each item in each list to compare the strings (that can be different each 'session'). I was also going to concatinate them together and add the final result into another List and write it to the final rich text box. However, I am getting lost and am pretty new to C#. Any help would be greatly appreciated.
Question: How can I compare these two text files, put them into a list properly, compare the two lists for values that are similar, replace the values in the first file with the following text from the matched values in the second file? If this is confusing, let me know!
Thanks in advance! :)
If your columns are delimited with spaces, or some other character(s), using string.Split to make an array of columns. Pick out the column you want and store it in a SortedList (column is both key and value), checking each time you add to ensure no duplicates are added. Read your second file one line at a time, foreach on SortedList keys, and if string.Contains the key, flag the line as having one of the column values.
I don't really get the formatting of your records because you say you are splitting with a space but your records won't split correctly on that. If your file is a fixed length file then you can use .substring to pull data out. If I am reading your question right I think you are going to want to read each line of the first file and add it the line into a hashset using the second column as a key and then the rest of the line as the value. Then cycle through the second file and for each value in the line find the key it goes with and print the value from the key along with the value of the line you just read. You can then find a spot to add a condition that if the key has an "A" or what not you also print a "T" at the end. I think you should stay away from the regex because performance is generally lacking and I don't think it's what you need here.
string strFileName = DisplayFile("Please Select File 1", ".txt", null);
StreamReader srInput = File.OpenText(strFileName);
Hashtable newHash = new Hashtable();
while(srInput.Peek > -1)
{
string temp = srInput.ReadLine();
string parts = temp.Split('//put delimiter here');
newHash.Add(parts[1]//your key should be your second column value,parts [2]//this is your value);
}
//then read in your second file and test each line to see if it has a match in the first file.
string strFileName2 = DisplayFile("Please Select File 2", ".txt", null);
StreamReader srInput2 = File.OpenText(strFileName);
while(srInput2.Peek > -1)
{
string temp2 = srInput.Readline();
string[] parts2 = temp2.Split('delim');
if(newHash.ContainsKey(parts[whichever is the column you want to check is]))
{
//then print to value to new file or list
//newList.Add(parts[that were checked] + newHash[parts that were checked]);
}
}
something like that will work.
Related
Append to the second to last line in a text file
So I'm making a program to type what's in my clipboard into a text file, I plan on later transporting this information into an AHK script, but I want to do this all in one program, so if possible it will append to the .ahk file, but instead of it appending to the very last line, I need it to append to the line before return, which is the final line of the file. Send ::redeem N4E2vzCEp {enter} Sleep 1000 return That's the end of the file, if possible I want my program to do something like: string pasted = Clipboard.GetText(); sw.WriteLine.SecondLastLine("Send ::redeem " + pasted + " {enter}"); sw.WriteLine.SecondLastLine("Sleep 1000"); //Fully aware that secondlastline is not a valid command But I don't know what the proper way of actually coding this would be. Current code: private void paste_Click(object sender, EventArgs e) { string path = #"c:\users\john\desktop\auths.txt"; using (StreamWriter sw = File.AppendText(path)) { string pasted = Clipboard.GetText(); sw.WriteLine("Send ::redeem " + pasted + " {enter}"); sw.WriteLine("Sleep 1000"); } }
What you can do is reading all lines into a List and then insert the new line at a specific position and write the lines back to the file. List<string> lines = File.ReadAllLines("your file").ToList(); lines.Insert(lines.Count - 2, "new line"); File.WriteAllLines("your file", lines);
How can i write multiple lines in a textfile to different textboxes?
What i did to write from the boxes to the txt file private void save2_Click(object sender, EventArgs e) { Stream myStream; SaveFileDialog sfd = new SaveFileDialog(); sfd.Filter = "Textdokument|*.txt"; sfd.FilterIndex = 1; sfd.RestoreDirectory = true; if (sfd.ShowDialog() == DialogResult.OK) { if ((myStream = sfd.OpenFile()) != null) { StreamWriter sw = new StreamWriter(myStream); sw.WriteLine(TextBoxCardname1.Text); sw.WriteLine(TextBoxCardname2.Text); sw.WriteLine(TextBoxCardname3.Text); sw.WriteLine(TextBoxCardname4.Text); sw.WriteLine(TextBoxCardname5.Text); sw.WriteLine(TextBoxCardname6.Text); sw.WriteLine(TextBoxCardname7.Text); sw.WriteLine(TextBoxCardname8.Text); sw.WriteLine(TextBoxCardname9.Text); sw.WriteLine(TextBoxCardname10.Text); sw.WriteLine(TextBoxCardname11.Text); sw.WriteLine(TextBoxCardname12.Text); sw.WriteLine(TextBoxCardname13.Text); sw.WriteLine(TextBoxCardname14.Text); sw.WriteLine(TextBoxCardname15.Text); sw.WriteLine(TextBoxCardname16.Text); sw.WriteLine(TextBoxCardname17.Text); sw.WriteLine(TextBoxCardname18.Text); sw.WriteLine(TextBoxCardname19.Text); sw.WriteLine(TextBoxCardname20.Text); sw.WriteLine(TextBoxCardname21.Text); sw.WriteLine(TextBoxCardname22.Text); sw.WriteLine(TextBoxCardname23.Text); sw.WriteLine(TextBoxCardname24.Text); sw.WriteLine(TextBoxCardname25.Text); sw.WriteLine(TextBoxCardname26.Text); sw.WriteLine(TextBoxCardname27.Text); sw.WriteLine(TextBoxCardname28.Text); sw.WriteLine(TextBoxCardname29.Text); sw.WriteLine(TextBoxCardname30.Text); sw.Close(); myStream.Close(); } } }
Assuming what you meant by your question is that you want to take the contents of each line of a textfile and write it to its corresponding textbox.text; this should work for you: TextBoxCardname1.Text = System.IO.File.ReadLines("Your Text File").Skip(0).Take(1).First(); TextBoxCardname2.Text = System.IO.File.ReadLines("Your Text File").Skip(1).Take(1).First(); TextBoxCardname3.Text = System.IO.File.ReadLines("Your Text File").Skip(2).Take(1).First(); //...etc For each line you're reading, you specify how many lines you want to skip, and how many lines you want to read (ie. Skip(1), Take (1) means you would skip the first line in the text file, and read the second line). If you're trying to get the textbox.text and write it to your textfile (it's kind of hard to tell from your question) This is a simple, yet messy, and labor-intensive method: var lines = System.IO.File.ReadAllLines("Your text file"); lines[0] = TextBoxCardname1.text); System.IO.File.WriteAllLines("Your text file", lines); var lines = System.IO.File.ReadAllLines("Your text file"); lines[1] = TextBoxCardname2.text); System.IO.File.WriteAllLines("Your text file", lines); var lines = System.IO.File.ReadAllLines("Your text file"); lines[2] = TextBoxCardname3.text); System.IO.File.WriteAllLines("Your text file", lines); //...etc This method is a very simple way to write to a certain line in a text file. lines[3] would denote the 4th line in the text file, since the line numbering starts at zero [0] (The first line in the text file).
How to create a text file, and naming it with a text box or variable
Hi im very new to c# so apologies for this. Im trying to create a text file to save customers details. But i want to name the text file by the surname. I.e myfile.txt. Im sure im close, but missing something when it comes to changing the surname.text to a variable then making it the name of my created new file. I have put 2 ** around the problem area. private void button1_Click(object sender, EventArgs e) { try { if ((tb_firstname.Text == "") || (tb_surname.Text == "") || (tb_postcode.Text == "")) { MessageBox.Show("Missing values from textboxes!"); } else if ( ****string myfile.txt = (tb_surname.Text); File.Exists("myfile.txt"));**** { if (MessageBox.Show("Warning: file already exists. " + "Contents will be replaced - " + "do you want to continue?", "File Demo", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.Yes) { //write lines of text to file StreamWriter outputStream = File.CreateText(myfile.txt); outputStream.WriteLine(tb_firstname.Text); outputStream.WriteLine(tb_surname.Text); outputStream.WriteLine(tb_surname.Text); outputStream.Close(); MessageBox.Show("Text written to file successfully!"); this.Close(); } else { MessageBox.Show("Action cancelled existing file contents not replaced!"); this.Close(); } } else { //write lines of text to file StreamWriter outputStream = File.CreateText("myFile.txt"); outputStream.WriteLine(tb_firstname.Text); outputStream.WriteLine(tb_surname.Text); outputStream.WriteLine(tb_postcode.Text); outputStream.Close(); MessageBox.Show("Text written to file successfully!"); this.Close(); } } catch (Exception problem) { MessageBox.Show("Program has caused an error - " + problem.ToString()); } } any help would be great!
You are creating a file called myfile.txt every time StreamWriter outputStream = File.CreateText("myFile.txt"); That's a string literal you are using. You have the line: string myfile.txt = (tb_surname.Text) which reads the contents of the text box into a variable called myfile.txt. You then need to use that in the file creation code: StreamWriter outputStream = File.CreateText(myFile.txt); Note that there are no quotes. This will overwrite the file if it already exists - if you want to append you will need to use the following method: StreamWriter outputStream = File.AppendText(myFile.txt);
I believe you are trying to save the surname as part of the file name. You can generate the filename and check if it exists with the code below: First generate the filename: string fileName = string.Format("{0}File.txt", tb_surname.Text); And then check it using the variable: File.Exists(fileName);
Text file doesn't get saved but no errors (C#)
I've been looking on many websites now for the answer, but all working answers only work for the richTextbox, and I'm using the normal textbox. I'm trying to save the contents of the textbox to a file of choice, but for some reason the file doesn't get saved, and I have no idea what the problem is. This is the code of the 'save' menu item: private void saveToolStripMenuItem_Click(object sender, EventArgs e) { SaveFileDialog ofd = new SaveFileDialog(); ofd.Title = "Save"; ofd.Filter = "Txt Documents (.txt)|*.txt|All files (*.*)|*.*"; if (ofd.ShowDialog() == DialogResult.OK) { try { //I don't know what to make of this, because clearly this doesn't work File.WriteAllText(#"./TestFile.txt", MainTextbox.Text); } catch (Exception ex) { MainTextbox.Text += ex; } } } There is no error.
You should be saving to the file selected in your SaveFileDialog, as retrieved by OpenFile(). This example worked for me: SaveFileDialog ofd = new SaveFileDialog(); ofd.Title = "Save"; ofd.Filter = "Txt Documents (.txt)|*.txt|All files (*.*)|*.*"; if (ofd.ShowDialog() == DialogResult.OK) { using (var fileStream = ofd.OpenFile()) using (var sw = new StreamWriter(fileStream)) sw.WriteLine("Some text"); } In your code, you let the user select a file to save to, then ignore that and write it to a hardcoded location. It's possible your app didn't have permissions to do this, but it should have permissions to write to a location the user selected.
First off, saving the file has nothing to do with where the text is coming from, rich text box or normal text box. As Brian S. said in a comment, it is likely there is an exception because you're writing to the C drive. You should use a relative path: "./MyTest.txt"
I think its access denied issue.. try with 'D' drive ... This is working example.. .WriteAllText works when file already exists and if file already exists then use AppendAllText using System; using System.IO; using System.Text; class Test { public static void Main() { string path = #"c:\temp\MyTest.txt"; // This text is added only once to the file. if (!File.Exists(path)) { // Create a file to write to. string createText = "Hello and Welcome" + Environment.NewLine; File.WriteAllText(path, createText); } // This text is always added, making the file longer over time // if it is not deleted. string appendText = "This is extra text" + Environment.NewLine; File.AppendAllText(path, appendText); // Open the file to read from. string readText = File.ReadAllText(path); Console.WriteLine(readText); } }
Use a try { } catch (Exception ex) { } block How to: Use the Try/Catch Block to Catch Exceptions
How to replace a data from a file if already exists and write a new data
Hi all i write a code to write my last row of datagrid view to a file as follows private void Save_Click(object sender, EventArgs e) { if (dataGridView1.Rows.Count > 0) { List<string> lstContent = new List<string>(); foreach (DataGridViewRow row in dataGridView1.Rows) { if ((string)row.Cells[0].Value == "FileControl") { lstContent.Add((string)row.Cells[1].Value); string mydata = string.Join(",", lstContent.ToArray()); using (StreamWriter sw = new StreamWriter(Append.FileName, true)) { sw.WriteLine(); sw.Write(mydata); } } } } } But if i click multiple times on save this is writing that line multiple times what i need is if already that line exists in the file i have to replace that line with new line. Any help please
Your StreamWriter is explicitly using the file with append = true. Change the second parameter of the constructor to false if you want to overwrite the file each time. Docs are here. Quote: append Type: System.Boolean Determines whether data is to be appended to the file. If the file exists and append is false, the file is overwritten. If the file exists and append is true, the data is appended to the file. Otherwise, a new file is created. Revised code: using (StreamWriter sw = new StreamWriter(Append.FileName, false)) { sw.WriteLine(); sw.Write(mydata); } Replacing a given line in your file rather than just overwriting the whole file is a lot more difficult - this code is not going to get it done. StreamWriter is not great for this, you need random access and the ability to replace one data segment (line) by a different data segment of different length, which is an expensive operation on disk. You might want to keep the files in memory as a container of Strings and do your required line replacement within the container, then write out the file to disk using File.WriteAllLines - that's if the file is not too big.