Can you help me on textchanged ans copy - c#

Hello I would like to be able to change the text of my txtFiles textbox at each iteration of files when there are several files.
And also be able to copy only one file at a time when I want it even if there are several files in the directory.
I declared the textchanged event.
I have declared the txtFiles_TextChanged function but I don't know what to put in it to make the text of the txtFiles textbox change with each iteration of files.
I declared txtFiles.Text = ConvertToString (files [i]);
to change the text in the textbox.
I would also like to be able to copy only one file at a time but it wipes out all the txt files.
How do you resolve this?
string sourceDir =
#"C:\Users\PORTABLEHP\Documents";
string destDir =
#"C:\Users\PORTABLEHP\Documents\
xgen";
public évent EventHandler
textchanged;
private void btnCopy(object
sender,EventArgs e)
{
try
{
string [] txtList = Directory.
GetFiles(sourceDir,"*.txt");
foreach(string f in txtList)
{
try
{
string fName = f.Substring
(sourceDir.Length + 1);
string [] files = new string
[sourceDir.Length];
progressBar1.Value = 1;
progressBar1.Minimum = 0;
progressBar1.Maximum =
files.Length;
for(int i = 1;i < files.Length;
i++)
{
progressBar1.PerformStep();
//To have the text change from the
textbox
txtFiles.Text = ConvertToString
(files[i]);
File.Copy(Path.Combine
(sourceDir,fName), Path.Combine
(destDir,fName), true);
}
}
catch(IOException copyerror)
{
MessageBox.Show(copyerror.Message);
}
}
}
catch (DirectoryNotFoundException
dirnotfound)
{
MessageBox.Show
(dirnotfound.Message);
private void txtFiles_TextChanged
(object sender,EventArgs e)
{
// I don't know ?
}

So if I got you right, you need to do a little change in your code
Change
txtFiles.Text = ConvertToString(files[i]);
To
txtFiles.Text = $"{ Path.GetFileName(f)} was copied"; //f was declared as string in your first loop that contains the file path

Related

Append string in a specific place of a text file

I have hundreds of files in a directory. Many of the text files have the Code Column values as blank and i need to iterate over all the text files and fill it. I am able to write the code to add the code value in a new line, but i am not able to write it under code column. String value is: "STRINGTOENTER". I only want it be entered in the 1st line after the header. The last line should be left alone
Id Code File_Number Suffix Check_Number Check_Date
047 7699 01 99999 11/11/2012
1 -6.15
Below is my code snippets that add the value at a newline. I think I need to do a regular expression or a tab delimited type solution here.
public static void AddAStringtoAllTextFiles()
{
try
{
string path = #"C:\Users\ur\Desktop\TestFiles\";
string[] fileEntries = Directory.GetFiles(path);
for (int i = 0; i < fileEntries.Length; i++)
{
File.AppendAllText(fileEntries[i], "STRINGTOENTER" + Environment.NewLine);
}
}
catch (Exception e)
{
throw e;
}
}
EDITED
please try this with the assumption that its space(s) delimited.
its working on my VS2017 and kindly add the using statement on the top as below .
using System.Text.RegularExpressions
public static void AddAStringtoAllTextFiles()
{
try
{
string path = #"C:\Users\ur\Desktop\TestFiles\";
var fileEntries = Directory.GetFiles(path);
int indexPosition2InsertData=1;
foreach (var entry in fileEntries)
{
var lines = File.ReadAllLines(entry);
for (var index = 1; index < lines.Length; index++) //starting from first row, leaving the header
{
var split= Regex.Split(lines[index].Trim(), #"\s{1,}"); //reading the line with space(s)
if(split.Length==5) //edited //checking if the row is not blank
{
var list = split.ToList(); //convert to list to insert
list.Insert(indexPosition2InsertData, "STRINGTOENTER"); //inserting at the index 1
lines[index] = string.Join("\t", list);
}
}
File.WriteAllLines(entry, lines);
}
}
catch (Exception e)
{
throw e;
}
}
I am getting this after running the code.
Id Code File_Number Suffix Check_Number Check_Date
047 STRINGTOENTER 7699 01 99999 11/11/2012
1 -6.15
Please let me know if this helps.
Assuming each file has the right tab delimitation (and that's a big assumption given the question quality)
// Get the files
var fileEntries = Directory.GetFiles(path);
// iterate through each file name
foreach (var entry in fileEntries)
{
// Load the File into the lines array
var lines = File.ReadAllLines(entry);
// Iterate over each line
if(lines.Length >1)
{
// Split the lines by tab
var split = lines[1].Split('\t');
// your code should be at array index 1
split[1] = "STRINGTOENTER";
// write the whole line back
lines[1] = string.Join("\t", split);
// write the file
File.WriteAllLines(entry, lines);
}
}
Note : you should probably do this with a CSV parser, this was only for academic purposes and totally untested
I want to show my desired solution based on your input. Amazing how a simple piece of code can contribute to solving a larger and a complex problem. Thanks again!
public static void AddClientCodetoAllTextFiles(string update_batch_with_clientcode, string batchfilepathtobeupdated)
{
try
{
var fileEntries = Directory.GetFiles(#batchfilepathtobeupdated.Trim());
foreach (var entry in fileEntries)
{
var lines = File.ReadAllLines(entry);
if (lines.Length > 1)
{
for (int i = 1; i < lines.Length - 1; i++)
{
var split = lines[i].Split('\t');
split[1] = update_batch_with_clientcode.Trim();
lines[i] = string.Join("\t", split);
File.WriteAllLines(entry, lines);
}
}
}
}
catch (Exception e)
{
throw e;
}
}

How read and search multiple txt files in listBox with (in) one button c#?

private void btnOpen_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == DialogResult.OK)
{
listBox1.Items.Clear();
string[] allfiles = Directory.GetFiles(fbd.SelectedPath, "*.txt*",
SearchOption.AllDirectories);
foreach (string file in allfiles)
{
FileInfo info = new FileInfo(file);
listBox1.Items.Add(Path.GetFileName(file));
}
}
}
There is listbox1 with all .txt files from direcory and subfolder...
Now I need from this listBox all files and search by some string.
Can I iterate loop and read file by file?
I don't have an idea how read and search files, need I open first, then store a data of file somewhere, maybe list or listView?
First, I would use a class of its own to store your search results. When we search files, and if we find the keyword we're searching for, we'd create an object of this class and at it to a list. Something like this:
public class SearchResults
{
public string FilePath { get; set; }
public string SearchWord { get; set; }
public int Occurences { get; set; }
}
Then you can use the System.IO.File class to read your files. Remember this is not the only way, but merely one way of doing it. Here I have a list of file names, which is equivalent to the array you have in your program.
var searchTerm = "Hello";
var fileList = new List<string>() { "A.txt", "B.txt", "C.txt" };
var resultList = new List<SearchResults>();
// Iterate through files. You already are doing this.
foreach (var file in fileList)
{
// Check to see if file exists. This is a second line of defense in error checking, not really necessary but good to have.
if (File.Exists(file))
{
// Read all lines in the file into an array of strings.
var lines = File.ReadAllLines(file);
// In this file, extract the lines contain the keyword
var foundLines = lines.Where(x => x.Contains(searchTerm));
if (foundLines.Count() > 0)
{
var count = 0;
// Iterate each line that contains the keyword at least once to see how many times the word appear in each line
foreach (var line in foundLines)
{
// The CountSubstring helper method counts the number of occurrences of a string in a string.
var occurences = CountSubstring(line, searchTerm);
count += occurences;
}
// Add the result to the result list.
resultList.Add(new SearchResults() { FilePath = file, Occurences = count, SearchWord = searchTerm });
}
}
}
The CountSubstring() helper method.
public static int CountSubstring(string text, string value)
{
int count = 0, minIndex = text.IndexOf(value, 0);
while (minIndex != -1)
{
minIndex = text.IndexOf(value, minIndex + value.Length);
count++;
}
return count;
}

C# insert text after each occurence of a text string using wildcards [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Solved:
This solution has been solved. I was modding a game and am creating a C# windows form to easily manipulate large quantities of repeating data, or expressions, and quickly insert mass changes to a file, or files. I was stuck on identifying a regular expression with Regex in my data files and inserting a text box field of data right after the expression I identified. The expression I have works in the regex editor, thanks to #Kris, but when I deployed it into my program, nothing happened. I apologize for not having my thoughts in order, I will be sure to be more clear next time I use SO.
Below is the data I wanted to manipulate, followed by the working code I was able to fix myself with pointers from #Kris and #Rufus L. Again, I needed to search for particular data strings and insert a new string underneath the data property in every occurrence in the file. Hope this helps someone.
The data properties text looks like this:
1234 = {
workers = {
culture = dudes
religion = awesome
size = 37800
}
professionals = {
culture = dudes
religion = awesome
size = 6000
}
leaders = {
culture = dudes
religion = awesome
size = 500
}
}
1235 = {
workers = {
culture = dudes
religion = awesome
size = 37800
}
professionals = {
culture = dudes
religion = awesome
size = 6000
}
leaders = {
culture = dudes
religion = awesome
size = 500
}
}
I only want to insert text into the parent #### = {} property that holds the child = {} property fields. IE, I want to insert textBox2.Text in a new line under 1234 = {
I have the regex expression linked on here, thanks to #Kris.
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
static string[] files;
static int curNum = 0;
static string[] txtFiles;
static string[] provinces;
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
System.IO.File.WriteAllText(pathText.Text + txtFiles[curNum], richTextBox1.Text);
}
private void prevButton_Click(object sender, EventArgs e) {
if(curNum > 0)
curNum--;
richTextBox1.Text = System.IO.File.ReadAllText(pathText.Text + txtFiles[curNum]);
filenameLabel.Text = txtFiles[curNum];
}
private void loadButton_Click(object sender, EventArgs e) {
curNum = 0;
txtFiles = GetFileNames(pathText.Text, "*.txt");
richTextBox1.Text = System.IO.File.ReadAllText(pathText.Text + txtFiles[curNum]);
filenameLabel.Text = txtFiles[curNum];
}
static string[] GetFileNames(string path, string filter) {
files = Directory.GetFiles(path, filter);
for (int i = 0; i < files.Length; i++)
files[i] = Path.GetFileName(files[i]);
return files;
}
private void nextButton_Click(object sender, EventArgs e) {
if(curNum < txtFiles.Length)
curNum++;
richTextBox1.Text = System.IO.File.ReadAllText(pathText.Text + txtFiles[curNum]);
filenameLabel.Text = txtFiles[curNum];
}
private void appendButton_Click(object sender, EventArgs e)
{
provinces = Regex.Matches(richTextBox1.Text, #"\d+(.*?){")
.Cast<Match>()
.Select(m => m.Value)
.ToArray();
for (int i = 0; i < provinces.Length; i++)
{
richTextBox1.Text = richTextBox1.Text.Replace(provinces[i], provinces[i] + System.Environment.NewLine + " " + textBox2.Text);
}
}
}
}
Use regex
\d+(.*?){
tested here
Another way to do it would be to insert the text at the end of each block, by searching for two } characters separated by 0 or more whitespace characters. The regex for this would look like:
Regex.Matches(searchString, "}\\s}");
In either case, when inserting the strings we should start from the last match (at the end of the string) and move backwards towards the beginning, because each insert will change the string length and therefore impact the index at which we want to do the insertion.
For example:
/// <summary>
/// Returns a string with newText inserted into parentText
/// </summary>
/// <param name="newText">The new text to insert</param>
/// <param name="parentText">The parent text to insert into</param>
/// <returns>The parent string with the newText inserted</returns>
private string GetInsertedText(string newText, string parentText)
{
var newParentText = parentText;
var matches = Regex.Matches(newParentText, "}\\s}");
// Replace from the last occurrence, since each insert will
// change the length of our string and alter the insert location
for(int index = matches.Count - 1; index >= 0; index--)
{
var match = matches[index];
newParentText = newParentText.Substring(0, match.Index + 1) +
Environment.NewLine + newText +
newParentText.Substring(match.Index + 1);
}
return newParentText;
}
You also might want to create a method that adds 4 spaces to the beginning of each line of the textBox1.Text so that it has a proper indent after it's inserted. For example:
private string GetIndentedText(string originalText, string indentText = " ")
{
return $"{indentText}{originalText}".Replace("\n", $"\n{indentText}").TrimEnd();
}
The usage of this would look something like:
private void button1_Click(object sender, EventArgs e)
{
// Check for any text requirements here (like it should contain
// an open brace, an equals sign, end with a close brace, etc.)
if (textBox1.Text.Length > 0)
{
// Insert the new (indented) text into our RichTextBox
richTextBox1.Text = GetInsertedText(GetIndentedText(textBox1.Text),
richTextBox1.Text);
// Clear the input textbox
textBox1.Text = "";
}
}

Reading specific lines with unknown placement in C#

I am trying to code a program to read out user-groups from a .txt-file and to put said groups into a listbox. An example for a group list would be the following:
User
-------------
Group1
Group2
Group3
[space]
[space]
next user
Every user has is in an unknown amount of groups, thats why there are two spaces, just to seperate everything.
Here is my progress so far:
private void Button_Click(object sender, RoutedEventArgs e) {
//users.txt contains all users
//in the same directory there are multiple lists with given groups
StreamReader sr = new StreamReader("c:\\ADHistory\\users.txt", System.Text.Encoding.Default);
string line = string.Empty;
try {
//Read the first line of text
line = sr.ReadLine();
//Continue to read until you reach end of file
while (line != null) {
listboxNames.Items.Add(line);
//Read the next line
line = sr.ReadLine();
}
//close the file
sr.Close();
}
catch (Exception f)
{
MessageBox.Show(f.Message.ToString());
}
finally
{
//close the file
sr.Close();
}
}
private void listboxNames_SelectionChanged(object sender, SelectionChangedEventArgs e) {
//as soon as you choose a user from the first list
//you may choose a date to look at all groups the user is in.
listboxDates.Items.Clear();
DirectoryInfo dinfo = new DirectoryInfo(#"C:\ADHistory");
FileInfo[] Files = dinfo.GetFiles("*.txt");
//this adds all dates into the second listbox
//and removes users.txt from the list.
foreach (FileInfo file in Files) {
listboxDates.Items.Add(file.Name);
}
for (int n = listboxDates.Items.Count - 1; n >= 0; --n)
{
string removelistitem = "users";
if (listboxDates.Items[n].ToString().Contains(removelistitem))
{
listboxDates.Items.RemoveAt(n);
}
//this displays the user below the listboxes,
//because of styling purposes
string user = Convert.ToString(this.listboxNames.SelectedItem);
labelName.Content = user;
}
}
//here we have my main problem.
//I can't find a solution to add the groups to the last listbox
private void listboxDates_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string user = Convert.ToString(labelName.Content);
listboxGroups.Items.Clear();
string path = "C:\\ADHistory\\";
path += Convert.ToString(this.listboxDates.SelectedItem);
foreach (string line in File.ReadLines(path))
{
if (line.Contains(user))
{
while (line != " ")
{
listboxGroups.Items.Add(line);
}
}
}
}
I really hope you can help me.
EDIT
This question has been answered, so there is no need for mor answers.
Thanks for all the comments :)
Your problem is, when the line for the user is found, you test if line == " " without proceeding to the next and your while loop should exit immediately then
Use for loop instead of for each. Have your while loop when you find the line for user as the same, and increase the loop variable with ++ inside the while loop and read the next line. Don't forget to check for the string array length before setting line = fileLines[lineIndex]
Therefore, here is the code that should work for you
string[] fileLines = File.ReadAllLines(path);
for (int lineIndex = 0; lineIndex < fileLines.Length; lineIndex++)
{
string line = fileLines[lineIndex];
if (line.Contains(user))
{
while(++lineIndex < fileLines.Length && (line = fileLines[lineIndex]) != " ")
{
listboxGroups.Items.Add(line);
}
break;
}
}
However, if the file is huge, you might want not to read all it's lines into memory, here is another approach which works with File.ReadLines()
IEnumerator<string> fileLines = File.ReadLines(path).GetEnumerator();
while (fileLines.MoveNext())
{
string line = fileLines.Current;
if (line.Contains(user))
{
while (fileLines.MoveNext())
{
line = fileLines.Current;
if (line == " ")
{
break;
}
listboxGroups.Items.Add(line);
}
break;
}
}

how I can copy the text in a specified field, without mention the line number

I have the next code :
private void button1_Click_1(object sender, EventArgs e)
{
string path = AppDomain.CurrentDomain.BaseDirectory.ToString();
var link = File.ReadLines(path + "test.txt").ToArray();
var lines = File.ReadAllLines(path + "test2.txt");
foreach (var txt in link )
{
if (txt.Contains("Output="))
{
var outputPath = txt.Split('=')[1];
if (File.Exists(path + "test2.txt"))
{
var modifiedLines = lines.Select(line =>
{
if (line.StartsWith("outlog=\""))
{
return string.Format("outlog=\"{0}\"", outputPath);
}
else
{
return line;
}
});
File.WriteAllLines(path+ "test2.txt", modifiedLines);
}
}
}
With this code I whan to copy what is after equel from Output="C:\temp\out.log"(who is in test.txt), after equal in outlog=(who is in test2.txt).
How I can copy the text who exists in one text file test.txt, in a specified location from a second field test2.txt, without mentioned the line number ?
Here I put just a row, but in my files text I have many rows, but I think I make this to work, I handle with another rows.
test.txt have
Licfile="C:\temp\lic.lic"
Output="C:\temp\out.log"
Title="name"
test2.txt have
outlog=
license=
lmgr_files=
license_path=
and after runing the code the test2.txt I want to looks like this:
outlog="C:\temp\out.log"
license_path="C:\temp\lic.lic"
lmgr_files=false
license=true
I am confused about your problem but i just want to try to give you an opinion. I hope it may be help you. But line numbers are really important for these problem.
String[] arrayOld = File.ReadAllLines(#"C:\test.txt");
String[] arrayNew = new string[arrayOld.Length];
if (arrayOld[0].Contains("Licfile=")) // If statements could be more
{
Array.Copy(arrayOld,0,arrayNew,0,2); // How many line will add
}
for (int i = 0; i < 2; i++)
{
File.AppendAllText(#"D:\test2.txt", arrayNew[i] + Environment.NewLine); // It'll add all lines
}
P.S.: Don't forget to add strings like lineOne = "outlog=" + locString; etc.

Categories