I want to read specific data from bat file (set values) and then write them into Textbox1.Text (these are first lines of file I want to read from) and I want to get values
XXXXX write to Textbox1.Text
YYYYY write to Textbox2.Text
ZZZZZ write to Textbox3.Text
SSSSS write to Textbox4.Text
#echo off
:::::: DANE LOGOWANIA DO BAZY DANYCH
:: Baza danych
set DB=XXXXX
:: Serwer Bazy danych
set DBServer=YYYYY
:: Login do bazy danych
set DBUser=ZZZZZ
:: Hasło do bazy danych
set DBPassword=SSSSS
Reading from file should be triggered from
private void mssqlbutton_Click(object sender, EventArgs e)
{
}
Then if someone change Textbox1.Text value it writes those values into file in the position it previously read from.
I've tried finding for a solution using regex, reading by lines but it doesn't work for me or I don't know at all how to do it.
To be precise, I'm just starting my adventure with C#, I'm not that familiar with it yet, so If you could explain to me as well instead of only providing a code I would be grateful :)
EDIT:
Actually it is not that small, whole bat file is like that:
http://wklej.to/sCQ6i
(I know bat file delete log file at the end but i will handle it)
And AppCode:
http://wklej.to/Z5IFd
Where in AppCode
DBServerInput.Text was Textbox1.Text
DBInput.Text was Textbox2.Text
DBUserInput.Text was Textbox3.Text
DBPasswordInput was Textbox4.Texte
So where did you get stuck? However, the first requirement is relative easy:
private void ButtonReadBatch_Click(object sender, EventArgs e)
{
string[] linesToShowInTextBox = File.ReadLines(#"C:\Temp\batchTest.bat")
.Select(l => l.Trim())
.Where(l => l.StartsWith("set ", StringComparison.InvariantCultureIgnoreCase) && l.Contains('='))
.Select(l => l.Split('=').Last().TrimStart())
.ToArray();
TextBox1.Lines = linesToShowInTextBox;
}
The second is more complicated, this should give you an idea. It's tested rudimentarily:
private void ButtonSumbitTextboxChangesToBatch_Click(object sender, EventArgs e)
{
string[] lines = textBox1.Lines;
if (lines.Length != 0)
{
int matchIndex = 0;
var lineInfos = File.ReadLines(#"C:\Temp\batchTest.bat")
.Select(l => l.Trim())
.Select((line, index) => {
bool isSetLine = line.StartsWith("set ", StringComparison.InvariantCultureIgnoreCase) && line.Contains('=');
return new{
line, index, isSetLine,
setIndex = isSetLine ? matchIndex++ : -1
};
});
string[] newLines = lineInfos
.Select(x => !x.isSetLine || x.setIndex >= lines.Length
? x.line
: string.Format("set {0}={1}",
x.line.Split(' ')[1].Split('=')[0].Trim(),
lines[x.setIndex]))
.ToArray();
File.WriteAllLines(#"C:\Temp\batchTest.bat", newLines);
}
}
So don't use the TextChanged event but another button, otherwise the event is called on any change which causes undesired effects.
You can use the System.IO.File-class and its static Methods to read data from a file. Especially the Method ReadAllLines should help you. Thus, you can iterate over the lines or use an index to address. foreach and for loops should work.
The String-class gives you the tools to deconstruct the data read, think of using the Methods Split or IndexOf.
Writing the data back to the file can also be done using the System.IO.File-class. The easiest way should be overwriting the complete file with all you values, since the amount of data is pretty low. Consider using the AppendLine-Method from the System.IO.File-class.
The given MSDN-Links should give you a good starting point for your research. I won't post code since you said you want to go onto the adventure for yourself ;-)
I'm weak in Regular Expression , this code string pattern = #"=(?<after>\w+)"; is to match the word after equal sign = , it's better if some experts show for a better way :D
string txtBatFile= "<physical path for batfile>";
if (File.Exists(txtBatFile))
{
StreamReader SR = new StreamReader(txtBatFile);
string strFileText= SR.ReadToEnd();
SR.Close();
SR.Dispose();
string pattern = #"=(?<after>\w+)";
MatchCollection matches = Regex.Matches(strFileText, pattern, RegexOptions.Multiline | RegexOptions.IgnoreCase);
ArrayList _strList = new ArrayList();
foreach (Match match in matches)
{
_strList.Add(match.Groups["after"].ToString());
}
Textbox1.Text = _strList[0].ToString();
Textbox2.Text = _strList[1].ToString();
Textbox3.Text = _strList[2].ToString();
Textbox4.Text = _strList[3].ToString();
}
Related
I am going to build a dictionary. Everything was fine. But there is a little problem. To stop blocking UI of my winform I run my long code inside a thread. As I know when I give our operation for a worker thread UI is not blocked. But when I run the project it is still blocking for milliseconds. I did a lot of thing to find out it. The issue is the code has a textbox
textBox2.Invoke((MethodInvoker)((() => textBox2.Text += aa[i].Trim() + Environment.NewLine + foundwords + Environment.NewLine+ Environment.NewLine)));
It blocks the UI for 200ms if I run the project for 2 seconds...
Here is the whole code inbutton click event
private void button1_Click_2(object sender, EventArgs e)
{
textBox2.Text = "";
Thread btthread = new Thread(() => {
foundwords = "";
string words = "";
textBox1.Invoke((MethodInvoker)(() => words = textBox1.Text));
string[] aa = words.Trim().Split('\n');
for (int i = 0; i < aa.Length; i++)
{
string authors = DictionaryWords;
foundwords = "";
while (authors.Contains("\n"+aa[i].Trim().ToLower()+"\t"))
{
int index = authors.IndexOf("\n" + aa[i].Trim().ToLower() + "\t");// find where 1st hello is
string sub = authors.Substring(index + ("\n" + aa[i].Trim().ToLower() + "\t").Length);// remove all before hello get string we named it sub
int indexx = sub.IndexOf("\n"); // find \n index
int final = index + ("\n" + aa[i].Trim().ToLower() + "\t").Length; // find the index after 1st hello
string substr = authors.Substring(index + ("\n" + aa[i].Trim().ToLower() + "\t").Length, indexx); // select string after hello and before \n
authors = sub.Substring(indexx);// remove all after
foundwords += substr.Trim() + " ,";
}
textBox2.Invoke((MethodInvoker)((() => textBox2.Text += aa[i].Trim() + Environment.NewLine + foundwords + Environment.NewLine+ Environment.NewLine)));
}
});
btthread.Start();
}
DictionarywWords is a big file which has meaning for sinhala language
I want to stop Blocking the UI. could somebody tell me , what I should do?
forget threads and embrace Tasks and async await.
Put your long running code in an extra method that returns the data which be later used to fill the controls.
private WhatEverDataTypeSuitsYou CreateData()
{
WhatEverDataTypeSuitsYou returnValue;
// here goes your long running code
return returnValue;
}
now you can make your click event handler also async and await the results in there. Since the method createData returns on the UI thread there will be no need for invokation. You can simply fill the controls with the data as you see fit
private async void button1_Click_2(object sender, EventArgs e)
{
var result = await Task.Run(CreateData);
// now fill the controls without invoke
}
EDIT: Actually on the second glance at you code, I would suggest to use a StringBuilder instead of concatenating strings. This is probably the reason why your code need so much time.
This particular line is the evil one:
foundwords += substr.Trim() + " ,";
If I've understood what you're trying to do then I think I've got a solution that will run much much faster than your approach.
You are building a destroying many many strings in your search for the words that appear in the text DictionaryWords.
I gather that the file that DictionaryWords looks somewhat like this:
apple\ta fruit\n
Apple\ta computer\n
Banana\t\a fruit\n
fan\tone who follows a celebrity\n
Fan\ta device that moves air\n
NB: If you're on a PC then the line endings are \r\n, but I'll just assume you are on Linux.
A better data structure for working with this data would be this:
ILookup<string, string> dictionary =
File
.ReadLines(#"Path_to_DictionaryWords.txt")
.Select(x => x.Split('\t'))
.ToLookup(x => x[0].ToLower(), x => x[1]);
So, given my data above this would look like:
Now if you take textBox1 we can do this to get a list of words:
string[] words =
textBox1
.Text
.ToLower()
.Split(
Environment.NewLine,
StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
So if the user had entered this:
banana
apple
Then you'd have this:
Now, it's simple to get out the matching values:
string output =
String.Join(
Environment.NewLine + Environment.NewLine,
from word in words
where dictionary[word].Any()
select $"{word}{Environment.NewLine}{String.Join(", ", dictionary[word])}");
That looks like:
banana
a fruit
apple
a fruit, a computer
That code will run much faster than yours and will produce the entire output in one go.
You may not need tasks or threads with this approach.
If you do, try this:
private async void button1_Click_2(object sender, EventArgs e)
{
ILookup<string, string> dictionary = await Task.Run(() =>
File
.ReadLines(#"Path_to_DictionaryWords.txt")
.Select(x => x.Split('\t'))
.ToLookup(x => x[0].ToLower(), x => x[1]));
string[] words =
textBox1
.Text
.ToLower()
.Split(
Environment.NewLine,
StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
string output = await Task.Run(() =>
String.Join(
Environment.NewLine + Environment.NewLine,
words.Select(w => $"{w}{Environment.NewLine}{String.Join(", ", dictionary[w])}")));
textBox2.Text = output;
}
How to get whole text from document contacted into the string. I'm trying to split text by dot: string[] words = s.Split('.'); I want take this text from text document. But if my text document contains empty lines between strings, for example:
pat said, “i’ll keep this ring.”
she displayed the silver and jade wedding ring which, in another time track,
she and joe had picked out; this
much of the alternate world she had elected to retain. he wondered what - if any - legal basis she had kept in addition. none, he hoped; wisely, however, he said nothing. better not even to ask.
result looks like this:
1. pat said ill keep this ring
2. she displayed the silver and jade wedding ring which in another time track
3. she and joe had picked out this
4. much of the alternate world she had elected to retain
5. he wondered what if any legal basis she had kept in addition
6. none he hoped wisely however he said nothing
7. better not even to ask
but desired correct output should be like this:
1. pat said ill keep this ring
2. she displayed the silver and jade wedding ring which in another time track she and joe had picked out this much of the alternate world she had elected to retain
3. he wondered what if any legal basis she had kept in addition
4. none he hoped wisely however he said nothing
5. better not even to ask
So to do this first I need to process text file content to get whole text as single string, like this:
pat said, “i’ll keep this ring.” she displayed the silver and jade wedding ring which, in another time track, she and joe had picked out; this much of the alternate world she had elected to retain. he wondered what - if any - legal basis she had kept in addition. none, he hoped; wisely, however, he said nothing. better not even to ask.
I can't to do this same way as it would be with list content for example: string concat = String.Join(" ", text.ToArray());,
I'm not sure how to contact text into string from text document
I think this is what you want:
var fileLocation = #"c:\\myfile.txt";
var stringFromFile = File.ReadAllText(fileLocation);
//replace Environment.NewLine with any new line character your file uses
var withoutNewLines = stringFromFile.Replace(Environment.NewLine, "");
//modify to remove any unwanted character
var withoutUglyCharacters = Regex.Replace(withoutNewLines, "[“’”,;-]", "");
var withoutTwoSpaces = withoutUglyCharacters.Replace(" ", " ");
var result = withoutTwoSpaces.Split('.').Where(i => i != "").Select(i => i.TrimStart()).ToList();
So first you read all text from your file, then you remove all unwanted characters and then split by . and return non empty items
Have you tried replacing double new-lines before splitting using a period?
static string[] GetSentences(string filePath) {
if (!File.Exists(filePath))
throw new FileNotFoundException($"Could not find file { filePath }!");
var lines = string.Join("", File.ReadLines(filePath).Where(line => !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line)));
var sentences = Regex.Split(lines, #"\.[\s]{1,}?");
return sentences;
}
I haven't tested this, but it should work.
Explanation:
if (!File.Exists(filePath))
throw new FileNotFoundException($"Could not find file { filePath }!");
Throws an exception if the file could not be found. It is advisory you surround the method call with a try/catch.
var lines = string.Join("", File.ReadLines(filePath).Where(line => !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line)));
Creates a string, and ignores any lines which are purely whitespace or empty.
var sentences = Regex.Split(lines, #".[\s]{1,}?");
Creates a string array, where the string is split at every period and whitespace following the period.
E.g:
The string "I came. I saw. I conquered" would become
I came
I saw
I conquered
Update:
Here's the method as a one-liner, if that's your style?
static string[] SplitSentences(string filePath) => File.Exists(filePath) ? Regex.Split(string.Join("", File.ReadLines(filePath).Where(line => !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line))), #"") : null;
I would suggest you to iterate through all characters and just check if they are in range of 'a' >= char <= 'z' or if char == ' '. If it matches the condition then add it to the newly created string else check if it is '.' character and if it is then end your line and add another one :
List<string> lines = new List<string>();
string line = string.Empty;
foreach(char c in str)
{
if((char.ToLower(c) >= 'a' && char.ToLower(c) <= 'z') || c == 0x20)
line += c;
else if(c == '.')
{
lines.Add(line.Trim());
line = string.Empty;
}
}
Working online example
Or if you prefer "one-liner"s :
IEnumerable<string> lines = new string(str.Select(c => (char)(((char.ToLower(c) >= 'a' && char.ToLower(c) <= 'z') || c == 0x20) ? c : c == '.' ? '\n' : '\0')).ToArray()).Split('\n').Select(s => s.Trim());
I may be wrong about this. I would think that you may not want to alter the string if you are splitting it. Example, there are double/single quote(s) (“) in part of the string. Removing them may not be desired which brings up the possibly of a question, reading a text file that contains single/double quotes (as your example data text shows) like below:
var stringFromFile = File.ReadAllText(fileLocation);
will not display those characters properly in a text box or the console because the default encoding using the ReadAllText method is UTF8. Example the single/double quotes will display (replacement characters) as diamonds in a text box on a form and will be displayed as a question mark (?) when displayed to the console. To keep the single/double quotes and have them display properly you can get the encoding for the OS’s current ANSI encoding by adding a parameter to the ReadAllText method like below:
string stringFromFile = File.ReadAllText(fileLocation, ASCIIEncoding.Default);
Below is code using a simple split method to .split the string on periods (.) Hope this helps.
private void button1_Click(object sender, EventArgs e) {
string fileLocation = #"C:\YourPath\YourFile.txt";
string stringFromFile = File.ReadAllText(fileLocation, ASCIIEncoding.Default);
string bigString = stringFromFile.Replace(Environment.NewLine, "");
string[] result = bigString.Split('.');
int count = 1;
foreach (string s in result) {
if (s != "") {
textBox1.Text += count + ". " + s.Trim() + Environment.NewLine;
Console.WriteLine(count + ". " + s.Trim());
count++;
}
else {
// period at the end of the string
}
}
}
I have a string that looks like this
2,"E2002084700801601390870F"
3,"E2002084700801601390870F"
1,"E2002084700801601390870F"
4,"E2002084700801601390870F"
3,"E2002084700801601390870F"
This is one whole string, you can imagine it being on one row.
And I want to split this in the way they stand right now like this
2,"E2002084700801601390870F"
I cannot change the way it is formatted. So my best bet is to split at every second quotation mark. But I haven't found any good ways to do this. I've tried this https://stackoverflow.com/a/17892392/2914876 But I only get an error about invalid arguements.
Another issue is that this project is running .NET 2.0 so most LINQ functions aren't available.
Thank you.
Try this
var regEx = new Regex(#"\d+\,"".*?""");
var lines = regex.Matches(txt).OfType<Match>().Select(m => m.Value).ToArray();
Use foreach instead of LINQ Select on .Net 2
Regex regEx = new Regex(#"\d+\,"".*?""");
foreach(Match m in regex.Matches(txt))
{
var curLine = m.Value;
}
I see three possibilities, none of them are particularly exciting.
As #dvnrrs suggests, if there's no comma where you have line-breaks, you should be in great shape. Replace ," with something novel. Replace the remaining "s with what you need. Replace the "something novel" with ," to restore them. This is probably the most solid--it solves the problem without much room for bugs.
Iterate through the string looking for the index of the next " from the previous index, and maintain a state machine to decide whether to manipulate it or not.
Split the string on "s and rejoin them in whatever way works the best for your application.
I realize regular expressions will handle this but here's a pure 2.0 way to handle as well. It's much more readable and maintainable in my humble opinion.
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
const string data = #"2,""E2002084700801601390870F""3,""E2002084700801601390870F""1,""E2002084700801601390870F""4,""E2002084700801601390870F""3,""E2002084700801601390870F""";
var parsedData = ParseData(data);
foreach (var parsedDatum in parsedData)
{
Console.WriteLine(parsedDatum);
}
Console.ReadLine();
}
private static IEnumerable<string> ParseData(string data)
{
var results = new List<string>();
var split = data.Split(new [] {'"'}, StringSplitOptions.RemoveEmptyEntries);
if (split.Length % 2 != 0)
{
throw new Exception("Data Formatting Error");
}
for (var index = 0; index < split.Length / 2; index += 2)
{
results.Add(string.Format(#"""{0}""{1}""", split[index], split[index + 1]));
}
return results;
}
}
}
I am trying to read lines from txt file into array and display it into a text box.
Here is my code:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack != true)
{
blogPostTextBox.Text ="";
string blogFilePath = Server.MapPath("~") + "/Blogs.txt";
string[] blogMessageArray = File.ReadAllLines(blogFilePath);
// this for loop code does not work..I think..
for (int i = 0; i < blogMessageArray.Length; i++)
{
string[] fileLineArray = blogMessageArray[i].Split(' ');
blogPostTextBox.Text = blogMessageArray[i] + System.Environment.New Line.ToString();
}
}
}
My text file contains several line and I am trying to split each line to array and display all lines into a text box using a for loop or while loop.
UPDATE:
For ASP.Net
var items =File.ReadAllLines(blogFilePath).SelectMany(line => line.Split()).Where(x=>!string.IsNullOrEmpty(x));
blogPostTextBox.Text=string.Join(Environment.NewLine, items)
and as a side note, it is better to use Path.Combine when you build path from multiple strings
string blogFilePath = Path.Combine( Server.MapPath("~") , "Blogs.txt");
also if (IsPostBack != true) is valid but you can do as
if (!IsPostBack)
Winform
If the Multiline property of the text box control is set to true, you can use TextBoxBase.Lines Property
blogPostTextBox.Lines =File.ReadAllLines(blogFilePath);
if you need to split each line and set as textbox text then
blogPostTextBox.Lines = File.ReadAllLines(blogFilePath).SelectMany(line => line.Split()).ToArray();
You have to set TextMode="MultiLine" in your TextBox(default value is SingleLine), then you could build the text with Linq in this way:
var allLinesText = blogMessageArray
.SelectMany(line => line.Split().Select(word => word.Trim()))
.Where(word => !string.IsNullOrEmpty(word));
blogPostTextBox.Text = string.Join(Environment.NewLine, allLinesText);
You need to append each line to the textbox. What you are doing above is overwriting the contents of the textbox with each new line.
string[] blogMessageArray = File.ReadAllLines("");
blogPostTextBox.Text = "";
foreach (string message in blogMessageArray)
{
blogPostTextBox.Text += message + Environment.NewLine;
}
Although rather than read in all the lines, and then write out all the lines, why don't you just write out all the text to the textbox?
blogPostTextBox.Text = File.ReadAllText();
Though you could do this in a loop, you really don't need to (or want to)
Replace your loop with with built in dot net methods that actually do what your need.
See String.Join()
public static string Join(
string separator,
params string[] value
)
This will combine all of the elements of blogMessageArray with your specified separator
('\n' in your case, HTML does not need "\r\n")
Then just assign this to the property blogPostTextBox.Tex
fairly new to C# here......What I'm trying to do is parse a bunch of text to a webpage from a .txt file uploaded to memory.
Here's what the .txt file looks like
.RES B7=121
.RES C12=554
.RES VMAX=4.7μV
Again, it goes on like this for another 50 or so .RES'...
I've successfully got it to parse, but not in the desired format...
Here's how I want it to look on the webpage
B7.........121
C12.........554
VMAX.........4.7μV
all inside of a hidden panel with id="outpt"... which is currently set to visible="false"
Here's the code i'm using in my C# Page
namespace Sdefault
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnUpld_Click(object sender, EventArgs e)
{
Stream theStream = file1.PostedFile.InputStream; //uploads .txt file to memory for parse
using (StreamReader sr = new StreamReader(theStream))
{
string tba;
while ((tba = sr.ReadLine()) != null)
{
string[] tmpArray = tba.Split(Convert.ToChar("=")); //Splits ".RES B7=121" to "B7"... but for some reason, It prints it as
//".RES B7.RES C12.RES VMAX"... I would ultimately desire it to be printed as shown above
Response.Write(tmpArray[0].ToString());
var.Text = tba;
outpt.Visible = true;
}
}
}
}
}
Any pointers in which direction I should go with this?
// Open the file for reading
using (StreamReader reader = new StreamReader((Stream)file1.PostedFile.InputStream))
{
// as long as we have content to read, continue reading
while (reader.Peek() > 0)
{
// split the line by the equal sign. so, e.g. if:
// ReadLine() = .RES B7=121
// then
// parts[0] = ".RES b7";
// parts[1] = "121";
String[] parts = reader.ReadLine().split(new[]{ '=' });
// Make the values a bit more bullet-proof (in cases where the line may
// have not split correctly, or we won't have any content, we default
// to a String.Empty)
// We also Substring the left hand value to "skip past" the ".RES" portion.
// Normally I would hard-code the 5 value, but I used ".RES ".Length to
// outline what we're actually cutting out.
String leftHand = parts.Length > 0 ? parts[0].Substring(".RES ".Length) : String.Empty;
String rightHand = parts.Length > 1 ? parts[1] : String.Empty;
// output will now contain the line you're looking for. Use it as you wish
String output = String.Format("<label>{0}</label><input type=\"text\" value=\"{1}\" />", leftHand, rightHand);
}
// Don't forget to close the stream when you're done.
reader.Close();
}
Not sure on your formatting, but a simple Split and Format will do the trick.
On your split, you're getting everything before the = sign, whereas from your description, you want everything after it. e.g.
while(...)
{
var line = String.Format("<label>{0}< />.........textbox>{0}< />",tba.Split('=')[1]);
Response.Write(line);
}
if you take .RES B7=121 and split it on "=" then the index 0 would be .RES B7 and index one would be 121
if you want to further subdivide you wil have to split index 0 again using Chr(32) which would yield .RES as 0 and B7 as 1.
Can be done inline as suggested above with string formatting.
It looks as though you want someling like
String.Format("<label>{0}< />.........textbox>{1}< />",tba.Split('=')[0].Split(' ')[1],tba.Split('=')[1].);
Ok.. you have several issues here..
first, you are spliting using the =.. so you are splitting the string in two parts...
.RES B7=121 comes to:
tmpArray[0] = .RES B7
tmpArray[1] = 121
To avoid another split, the best you can do is to replace .RES with and empty string:
tmpArray[0] = tmpArray[0].replace(".RES","");
Then, you should be showing this somewhere on your page, so you should be writting:
Response.Write("<label>" + tmpArray[0].ToString() + "< />" + "<textbox>" + tmpArray[1].ToString() + "< />");
Looks like you need to do 2 splits:
1st var tmpArr1 = tba.Split(' ') will result in a string array {".RES","B7=121"}
2nd var tmpArr2 = tmpArr1[1].split('=') will result in a string array {"B7","121"}
Then you can do:
var line = String.Format("<label>{0}</label><textbox>{1}</textbox>",tmpArr2[0],tmpArr2[1]);
Response.Write(line);