I have created a project in C# windows form application. I am using .Net framework version 4.0 and Visual studio 2010.
Project contains Save and load File button. And also some textboxes.
I created a text file like this
Serial Number = 1
Type Number = 500
Test Engineer = jay
Date = 03/05/2018
Time = 16:17:20 PM
Test1 = 1.00
Test2 = 1.76
.
.
.
Test18 = 4.66
Code for Load File button:
private void btn_LoadFile_Click(object sender, EventArgs e)
{
OpenFileDialog fdlg = new OpenFileDialog();
if (fdlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
System.IO.StreamReader sr = new
System.IO.StreamReader(fdlg.FileName);
string[] lines = sr.ReadToEnd().Split('\n');
tb_SerialNo.Text = lines[0];
tb_TypeNo.Text = lines[1];
tb_TestEngineer.Text = lines[2];
tb_Date.Text = lines[3];
tb_Test1.Text = lines[4];
tb_Test2.Text = lines[5];
}
}
When I run above code, I got value in Serial no textbox is Serial Number = 1 but I want 1in textbox. Same Type Number Tex box Type Number = 500 but here also I want 500 in Type number textbox.
When you split by new line, lines[0] will store Serial Number = 1. Here you need to split it again by =.
If you try and print values of each element from string array, you will understand what changes you need to do in your code.
private void btn_LoadFile_Click(object sender, EventArgs e)
{
OpenFileDialog fdlg = new OpenFileDialog();
if (fdlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
System.IO.StreamReader sr = new
System.IO.StreamReader(fdlg.FileName);
string[] lines = sr.ReadToEnd().Split('\n'); //To make your code more readable, you can use "Environment.NewLine" instead of '\n'
Console.WriteLine(lines[0]); //Here it will give "Serial Number = 1"
// you need to store 1 in tb_SerialNo.Text, so split lines[0] with =
//Have you tried with this.
string[] splitWithEqualTo = lines[0].Split('=');
tb_SerialNo.Text = splitWithEqualTo [1];
//Similar kind of logic you can apply for other text boxes.
}
}
To fix your issue, you can try with the followings
Console.WriteLine(lines[0]); // This will print "Serial Number = 1"
string[] slitLine = lines[0].Split('=');
Console.WriteLine(slitLine[0]); //This will print "Serial Number"
Console.WriteLine(slitLine[1]); //This will print 1, this is what you need to store in tb_SerialNo.Text, right?
This is not the solution, but you will understand what changes you need to do in your code.
private void btn_LoadFile_Click(object sender, EventArgs e)
{
OpenFileDialog fdlg = new OpenFileDialog();
if (fdlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
System.IO.StreamReader sr = new
System.IO.StreamReader(fdlg.FileName);
string[] lines = sr.ReadToEnd().Split('\n');
PrintText(tb_SerialNo, lines[0]);
PrintText(tb_TypeNo , lines[1]);
PrintText(tb_TestEngineer, lines[2]);
PrintText(tb_Date, lines[3]);
PrintText(tb_Test1, lines[4]);
PrintText(tb_Test2, lines[5]);
}
}
private void PrintText(TextBox control, string line)
{
var splitline = line.Split('=');
control.Text = splitline[1];
}
try this
You could use string.Split() or string.LastIndexOf() to extract the part you need from the original string.
For example:
Here, we split the string in two when a '=' char is found. The extra space is lifted by Trim(), which is used to remove white spaces from the leading and trailing parts of a string.
tb_Test2.Text = lines[5].Split('=').Last().Trim();
or
LastIndexOf() finds the symbol specified, starting its search from the end of a string and returns its position (if it finds it, otherwise -1).
Substring() generates a new string from the supplied one, starting from a position and taking a specified number of characters.
Here, starting from the index returned by LastIndexOf() and including all the characters to the end of the string (if you don't specify how many characters it has to take, it takes them all. It's a method overload).
tb_Date.Text = lines[3].Substring(lines[3].LastIndexOf("=") + 1).TrimStart();
In both cases, the original string remains untouched.
You can also create a new array from the original one, containing only the required parts and then assign the values of the new array:
string[] lines2 = lines.Select(s => s.Split('=').Last().Trim()).ToArray();
tb_SerialNo.Text = lines2[0];
tb_TypeNo.Text = lines2[1];
//(...)
Related
I have 10 different textbox control and a textfile upload script on a button click. I want that when a user uploads a textfile which probably will consist 300 lines, it gets divided into 10 different textbox, 30 lines in each textbox, where each line separated with comma. I have used array to store textfile items.
private void button9_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string file = openFileDialog1.FileName;
string[] text = System.IO.File.ReadAllLines(file);
button9.Text = textBox13.Text.ToString();
textBox1.Text = string.Join("," + Environment.NewLine, text.Take(30));
if (text.Length > 30)
textBox2.Text = string.Join("," + Environment.NewLine, text[0]);
}
}
Here is some code you can use for that, an explanation follows:
string[] text = System.IO.File.ReadAllLines(file);
var thirtyLineSections = text
.Select((line, index) => new { line, group = index / 30 })
.GroupBy(item => item.group)
.ToArray();
int textboxIndex = 0;
foreach (var section in thirtyLineSections)
{
string textForSection = string.Join(",",
section.Select(item => item.line).ToArray()); // see note below
textboxes[textboxIndex].Text = textForSection;
textboxIndex++;
}
Note: If you're using .NET 4.0 or above you can remove the call to .ToArray(), and instead use this line for the one with the comment:
section.Select(item => item.line));
So, what will this code do?
First, it'll take each line from the original file and run that through a .Select(...) method. This method will be given a 0-based index and the actual element (line) from the original collection. In other words, the delegate to the Select method will be passed the value 0,"first line", 1,"second line", 2,"third line", and so on. We divide this by 30 to get a "group number", where the first group will be number 0, and so on. Then we group on that group number to put all the lines with the same group number into the same group.
In other words, you got this:
original file with index after dividing by 30
line 1 0,line 1 0,line 1
line 2 1,line 2 0,line 2
line 3 2,line 3 0,line 3
some text 3,some text 0,some text
line 5 4,line 5 0,line 5
...
line 30 29,line 30 0,line 30
line 31 30,line 31 1,line 31
So out of that LINQ query we will get an array of elements, where each element is a group that contains 30 lines of text from the original file, in the order they occured in.
Then we loop on that array, handling 30 elements at a time, and combining them into one string using string.Join, assigning the result to a textbox.
Before executing this code you need to do this:
var textboxes = new[]
{
textbox1,
textbox2,
...
textboxN
};
to create an array of the textboxes you want to assign those strings to.
Note: This code does not ensure that you have enough textboxes. If you've dropped 10 textboxes on the form, capable of handling 300 elements, and got more than 300 lines in that file, the code will throw an exception.
OK, as was pointed out in a comment, the LINQ query "looks good", but may be hard to understand for new programmers. I totally agree, so here is a different way to accomplish the same thing:
string[] text = System.IO.File.ReadAllLines(file);
var thirtyLineSections = new List<List<string>>();
List<string> currentList = null;
foreach (string line in text)
{
if (currentList == null)
{
currentList = new List<string>();
thirtyLineSections.Add(currentList);
}
currentList.Add(line);
if (currentList.Count == 30)
currentList = null;
}
foreach (var section in thirtyLineSections)
{
string.Join(",", section).Dump();
}
So what will this code do?
First it'll create the data structure, which in this case will be a "list of 30-line lists", ie. the List<List<string>> declaration.
Then it will loop through all the lines in the file. For each line it will check if we're currently in a group, and we start as "not in a group" so the answer is no, so then we'll create a new group and add this to our list.
Then we keep filling this list with items, until it hits 30 items, and then we simply say "ok, so this group is done, we're no longer in that group". The next line this loop processes will go through that if-statement again adding a fresh group for the next (and following) items.
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
I'm running three counters, one to return the total amount of chars, one to return the number of '|' chars in my .txt file (total). And one to read how many separate lines are in my text file. I'm assuming my counters are wrong, I'm not sure. In my text file there are some extra '|' chars, but that is a bug I need to fix later...
The Message Boxes show
"Lines = 8"
"Entries = 8"
"Total Chars = 0"
Not sure if it helps but the .txt file is compiled using a streamwriter, and I have a datagridview saved to a string to create the output. Everything seems okay with those functions.
Here is a copy of the text file I'm reading
Matthew|Walker|MXW320|114282353|True|True|True
Audrey|Walker|AXW420|114282354|True|True|True
John|Doe|JXD020|111222333|True|True|False
||||||
And here is the code.
private void btnLoadList_Click(object sender, EventArgs e)
{
var loadDialog = new OpenFileDialog
{
InitialDirectory = Convert.ToString(Environment.SpecialFolder.MyDocuments),
Filter = "Text (*.txt)|*.txt",
FilterIndex = 1
};
if (loadDialog.ShowDialog() != DialogResult.OK) return;
using (new StreamReader(loadDialog.FileName))
{
var lines = File.ReadAllLines(loadDialog.FileName);//Array of all the lines in the text file
foreach (var assocStringer in lines)//For each assocStringer in lines (Runs 1 cycle for each line in the text file loaded)
{
var entries = assocStringer.Split('|'); // split the line into pieces (e.g. an array of "Matthew", "Walker", etc.)
var obj = (Associate) _bindingSource.AddNew();
if (obj == null) continue;
obj.FirstName = entries[0];
obj.LastName = entries[1];
obj.AssocId = entries[2];
obj.AssocRfid = entries[3];
obj.CanDoDiverts = entries[4];
obj.CanDoMhe = entries[5];
obj.CanDoLoading = entries[6];
}
}
}
Hope you guys find the bug(s) here. Sorry if the formatting is sloppy I'm self-taught, no classes. Any extra advice is welcomed, be as honest and harsh as need be, no feelings will be hurt.
In summary
Why is this program not reading the correct values from the text file I'm using?
Not totally sure I get exactly what you're trying to do, so correct me if I'm off, but if you're just trying to get the line count, pipe (|) count and character count for the file the following should get you that.
var lines = File.ReadAllLines(load_dialog.FileName);
int lineCount = lines.Count();
int totalChars = 0;
int totalPipes = 0; // number of "|" chars
foreach (var s in lines)
{
var entries = s.Split('|'); // split the line into pieces (e.g. an array of "Matthew", "Walker", etc.)
totalChars += s.Length; // add the number of chars on this line to the total
totalPipes = totalPipes + entries.Count() - 1; // there is always one more entry than pipes
}
All the Split() is doing is breaking the full line into an array of the individual fields in the string. Since you only seem to care about the number of pipes and not the fields, I'm not doing much with it other than determining the number of pipes by taking the number of fields and subtracting one (since you don't have a trailing pipe on each line).
In my C# program (at this point) I have two fields in my form. One is a word list using a listbox; the other is a textbox. I have been able to successfully load a large word list into the listbox from a text file. I can also display the selected item in the listbox into the textbox this way:
private void wordList_SelectedIndexChanged(object sender, EventArgs e)
{
string word = wordList.Text;
concordanceDisplay.Text = word;
}
I have another local file I need to get at to display some of its contents in the textbox. In this file each headword (as in a dictionary) is preceded by a #. So, I would like to take the variable 'word' and search in this local file to put the entries into the textbox, like so:
#headword1
entry is here...
...
...
#headword2
entry is here...
...
...
#headword3
entry is here...
...
...
You get the format of the text file. I just need to search for the correct headword with # before that word, and copy all info from there until the next hash in the file, and place it in the text box.
Obviously, I am a newbie, so be gentle. Thanks much.
P.S. I used StreamReader to get at the word list and display it in the listbox like so:
StreamReader sr = new StreamReader("C:\\...\\list-final.txt");
string line;
while ((line = sr.ReadLine()) != null)
{
MyList.Add(line);
}
wordList.DataSource = MyList;
var sectionLines = File.ReadAllLines(fileName) // shortcut to read all lines from file
.SkipWhile(l => l != "#headword2") // skip everything before the heading you want
.Skip(1) // skip the heading itself
.TakeWhile(l => !l.StartsWith("#")) // grab stuff until the next heading or the end
.ToList(); // optional convert to list
string getSection(string sectionName)
{
StreamReader sr = new StreamReader(#"C:\Path\To\file.txt");
string line;
var MyList = new List<string>();
bool inCorrectSection = false;
while ((line = sr.ReadLine()) != null)
{
if (line.StartsWith("#"))
{
if (inCorrectSection)
break;
else
inCorrectSection = Regex.IsMatch(line, #"^#" + sectionName + #"($| -)");
}
else if (inCorrectSection)
MyList.Add(line);
}
return string.Join(Environment.NewLine, MyList);
}
// in another method
textBox.Text = getSection("headword1");
Here are a few alternate ways to check if the section matches, in rough order of how accurate they are in detecting the right section name:
// if the separator after the section name is always " -", this is the best way I've thought of, since it will work regardless of what's in the sectionName
inCorrectSection = Regex.IsMatch(line, #"^#" + sectionName + #"($| -)");
// as long as the section name can't contain # or spaces, this will work
inCorrectSection = line.Split('#', ' ')[1] == sectionName;
// as long as only alphanumeric characters can ever make up the section name, this is good
inCorrectSection = Regex.IsMatch(line, #"^#" + sectionName + #"\b");
// the problem with this is that if you are searching for "head", it will find "headOther" and think it's a match
inCorrectSection = line.StartsWith("#" + sectionName);
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);