I have a little project. What I am doing is, taking inputs from users and saving it in a text file. Its working good.
private void btbsave_Click(object sender, EventArgs e)
{
//Create Directory
DirectoryInfo dd = new DirectoryInfo("C://Program Files/UserInfo");
dd.Create();
//To save the inputs
StreamWriter sw = new StreamWriter("C://Program Files/UserInfo/UserInfo.txt", true);
sw.WriteLine(txtname.Text);
sw.WriteLine(txtage.Text);
sw.Flush();
sw.Close();
//Conformation
MessageBox.Show("Credentials Saved");
//To Clear the text box after data saved
txtname.Text = string.Empty;
txtage.Text = string.Empty;
//Focus
txturl.Focus();
}
And now, I want to retrieve the data depending on the inputs. This part is difficult for me, can you guys help me out?
private void btnsearch_Click(object sender, EventArgs e)
{
StreamReader sr = new StreamReader("C://Program Files/UserInfo/UserInfo.txt");
String mystring = sr.ReadToEnd();
//No idea how to retrive now plz help!
}
Brief description of my project:
Take some values from users like UserName and Age. Save them in a text file.
I need to retrieve values based on user UserName. I should then get UserName along with his Age and insert these values into 2 different readonly text boxes.
Personally I'd advise you to rethink your approach, but here's what you're looking for:
string sUserToSearch = "username";
string sAgeToSearch = "22";
string[] readText = File.ReadAllLines("UserInfo.txt");
for (int i = 0; i < readText.count-2; i++) {
if(readText[i] == sUserToSearch && readText[i+1] == sAgeToSearch);
// Found it!
}
I don't know what you're trying to do, but if I got you correct, you should read more on Serialization
First you have to seperate your data at the time, you insert them to your textfile
private void WriteUserToFile(User user, string path)
{
using(var sw = new StreamWriter(path, true))
{
sw.WriteLine(user.Name + ";" + user.Age);
}
}
Now you have a file like this:
User1;10
User2;20
User3;45
Now you have the possibility to split your data:
private IEnumerable<User> ReadUsersFromTextFile(string path)
{
var users = new List<User>();
using(var sr = new StringReader(path)
{
do
{
var strings = sr.ReadLine().split(';');
var user = new User();
user.Name = strings[0];
user.Age = strings[1];
users.Add(user);
}while(!sr.EndOfStream)
}
return users;
}
Related
I'm trying to make a login system with the sign-up already completed. I want to make it where you press the login button then it uses StreamReader to read the file that has been updated with my sign-up form. The problem is that I have structured how the file is written (example: when a user enters their details it saves their details in a structure like Username: johndoe Password: Password1 using StreamWriter in my sign-up form). But when I use StreamReader it reads the whole line instead of some parts. How would I read only some parts of my text file?
Code for sign-up form:
bool valid = true;
List<string> errorMessages = new List<string>();
if (string.IsNullOrWhiteSpace(txtUsername.Text))
{
valid = false;
errorMessages.Add("Username cannot be left empty.");
}
if (string.IsNullOrWhiteSpace(txtPassword.Text))
{
valid = false;
errorMessages.Add("Please enter a password.");
}
if (txtConfirmPass.Text != txtPassword.Text)
{
valid = false;
errorMessages.Add("Passwords do not match. Please enter matching passwords.");
}
if (valid == false)
{
string message = string.Join(Environment.NewLine, errorMessages);
MessageBox.Show(message, "Validate Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else if(valid == true)
{
Random rnd = new Random();
string userID = rnd.Next(0, 100000).ToString("D6");
//Use StreamWriter class.
using (StreamWriter sw = new StreamWriter("Test.txt", true))
{
sw.Write("\n" + "UserID: " + userID + "\n");
sw.Write("Username: " + txtUsername.Text + "\n");
sw.Write("Password: " + txtPassword.Text + "\n");
sw.Write("------------------------------------");
MessageBox.Show("Details have been saved");
frmLogin login = new frmLogin();
login.Show();
this.Hide();
}
}
Code for login form:
private void btnLogin_Click(object sender, EventArgs e)
{
bool valid = false;
using (StreamReader sr = new StreamReader("Test.txt"))
{
if(txtboxUser.Text == sr.ReadToEnd() && txtboxPass.Text == sr.ReadToEnd())
{
valid = true;
MessageBox.Show("Granted.");
}
else if(valid == false)
{
MessageBox.Show("Error");
}
}
}
Do you want to check if the user has entered the correct username and password by traversing the txt file?
Test info structure:
UserID: 016696
Username: kkk
Password: p123
Here is a simple you can refer to.
private void btnLogin_Click(object sender, EventArgs e)
{
string username = "";
string password = "";
bool ischecked = false; // check if the Username line is read
bool loginsuccess = false; // check if succeed
string line;
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader("Test.txt");
while ((line = file.ReadLine()) != null)
{
// if true, this is password line
if (ischecked)
{
// get password
// call Trim to remove extra spaces
password = line.Split(':')[1].Trim();
// check username and password
if (txtUsername.Text == username && txtPassword.Text == password)
{
MessageBox.Show("Login Successfully");
loginsuccess = true; // login in success
break;
}
// reset boolean
ischecked = false;
}
// read Username line, next line is the corresponding password
if (line.Split(':')[0] == "Username")
{
username = line.Split(':')[1].Trim();
// set boolean to true
ischecked = true;
}
}
file.Close();
// login failed
if(!loginsuccess)
{
MessageBox.Show("Wrong username or password");
}
}
You can try to use ReadLine() method in StreamReader like the one shown below, you should keep track that 2nd line contains the user name and the 3rd line contains the password. Also, you should use a Regex to split and get the values from the text or you could use a : delimiter and trim the values before comparison.
using (StreamReader sr = new StreamReader(path))
{
int counter = 0;
while (sr.Peek() >= 0)
{
string content = sr.ReadLine();
var userName = content.split(':')[1].trim()...
counter++;
}
}
Note:
The StreamReader directly reads from the file, so you have to perform string manipulation operations. Instead, you might also consider other approaches like a cache or a database operation to persist the values across pages / windows.
You have problems with your code, because you want to do too much in one method. You should separate your concerns
In your case: you shouldn't mix the communication with operator with the way that the input data is serialized.
If you separate the HMI from the way you save and read the input:
Easier to reuse: if you need to read the saved logged in data, without having to ask it from the operator again: just read it.
Easier to change: if you want a different HMI, you can still save in in the original format. If you want to save it in encrypted format, your HMI doesn't need to change.
Easier to Test: you can unit test Save / Read the file, without needing the operator input.
So separate the HMI from saving / reading the file, separate from processing the login data. This will take some extra typing, but your code will be much easier to understand, much easier to test, and future changes will have less impact on existing code.
For this you'll need a class that contains the login data. Something like this:
class User
{
public int Id {get; set;}
public string Name {get; set;}
public string Password {get; set;}
}
HMI for users
To display a User in the HMI, or to fetch it from the HMI. In your form class:
public User ReadUser()
{
return new User
{
Id = this.CreateUserId(),
Name = this.txtUserName.Text,
Password = this.txtPassword.Text,
};
}
// not sure if you need this:
public void DisplayUser(User user)
{
this.txtUserName.Text = user.Name,
this.txtPassword.Text = user.Password,
}
Consider to create a property:
public User User
{
get => new User {Id = this.CreateUserId(), ...},
set
{
this.txtUserName.Text = value.Name,
...
}
}
If in future you want to display users differently, like in a DataGridView, or a ComboBox, there will be only once place where you'll have to implement the changes.
Serializing users
My advice would be to stick to common formats, like CSV, XML, JSon. This would make life so much easier for you, because you can use NUGET packages for this.
If you can't convince your project leader that this would be a better solution and he still wants you to user you home invented format, you need two methods:
public void Serialize(User user, string fileName)
{
using (var textWriter = System.IO.File.CreateText(fileName, ...))
{
... // see your own code
}
}
By the way: why do you write `\n, why don't you use TextWriter.WriteLine
Deserialize a User
Currently your file has the following layout:
empty line
A line with "UserId: " + Id
A line with "UserName: " + Name
A line with "Password: " + Password
public User Deserialize(string fileName)
{
using (var textReader = System.IO.File.OpenText(fileName, ...))
{
string emptyLine = textReader.ReadLine();
if (emptyLine == null)
... // TODO: decide what to do if invalid file format. Exception?
string txtId = textReader.ReadLine();
if (txtId == null)
... // TODO: decide what to do if invalid file format
int id = Int32.Parse(txtId);
// TODO: handle invalid txtId format. Exception?
string name = textReader.ReadLine();
string password = textReader.ReadLine();
// TODO: handle invalid name / password;
return new User
{
Id = id,
Name = name,
Password = password,
}
}
}
Do you see, that if in future you change the format in which Users are saved, that you only need to change the two serialization methods? for instance, if you think that passwords need to be encrypted in the file, or if you think that JSON format is better.
Because of the separation of concerns, you can use the serialization of Users also in case you don't need to display it.
The separation of concerns also makes unit test easier
}
}
sw.Write("\n" + "UserID: " + userID + "\n");
sw.Write("Username: " + txtUsername.Text + "\n");
sw.Write("Password: " + txtPassword.Text + "\n");
sw.Write("------------------------------------");
I am new to Windows form application I want to Save Data in file except in (Sql) or database.I tried many things and I am able to store only one value in text file using it
TextWriter txt = new System.IO.StreamWriter("E:\\Tahir\\ScaleSystemDataSave\\First.txt");
txt.Write(txtFirsrWeight.Text);
txt.Close();
but I Want to Store an Object in file how can I Do it My object is like this
private void btnSave_Click(object sender, EventArgs e)
{
FirstTime obj = new FirstTime();
obj.CardNo = txtCardNo.Text;
obj.DateTime = txtDateTimePicker.Value;
obj.VehicleNo = txtVehicalNo.Text;
obj.WeightType = Convert.ToString(cbxWeigtType.SelectedItem);
obj.FirstWeight = txtFirsrWeight.Text;
if (rbtWithDriver.Checked == true)
{
obj.IsDriver = (int)Status.WithDriver;
}
else if (rbtWithouDriver.Checked == true)
{
obj.IsDriver = (int)Status.withOutDriver;
}
}
You have 2 options available to you.
Format the text file yourself like a comma delimited file and then read the file back in, parse it and assign the values back to your object.
Use a known serialization technique such as XML or JSON.
Below is an example of JSON serialization that achieves what you need.
var first = new FirstTime()
{
CardNo = "121515611",
Date = DateTime.Now.Date,
VehicleNo = "MNRG23434",
WeightType = "MyWeight",
FirstWeight = "FirstWeight"
};
var fileText = JsonConvert.SerializeObject(first);
TextWriter txt = new StreamWriter("C:\\First.txt");
txt.Write(fileText);
txt.Close();
var fileStream = File.Open("C:\\First.txt",FileMode.Open);
var fileReader = new StreamReader(fileStream);
var contents = fileReader.ReadToEnd();
var restoredObject = JsonConvert.DeserializeObject<FirstTime>(contents);
This stores the data in format as per the below
{"CardNo":"121515611","Date":"2017-03-16T00:00:00+00:00","VehicleNo":"MNRG23434","WeightType":"MyWeight","FirstWeight":"FirstWeight"}
Hope that helps you.
I have created 3 multi-line textboxes and I would like to write and save them to a .txt file. For example if I enter to my first textbox "John" on the first line and "Sakura" on the second line. Then if I enter "Bill" on the first line and "Sasuke on the second" to my second multi-line textbox and the same kind of text to my third textbox. I have a button to save it to a file. I would like the information in the text file to be shown as this:
This is what I have so far.
Hope my question is clear.
private void btn_Text1_Click(object sender, EventArgs e)
{
SaveFileDialog SaveFileDialog = new SaveFileDialog();
SaveFileDialog.Title = "Save As";
SaveFileDialog.Filter = "Text File (*.txt)|*.txt";
SaveFileDialog.InitialDirectory = #"C:\";
if (SaveFileDialog.ShowDialog() == DialogResult.OK)
{
FileStream fs = new FileStream(SaveFileDialog.FileName, FileMode.Create);
using (StreamWriter objWriter = new StreamWriter(fs))
{
objWriter.WriteLine("Names: ");
objWriter.WriteLine(txt_FName.Text);
objWriter.WriteLine("-------------------");
objWriter.WriteLine("Last Names: ");
objWriter.WriteLine(txt_LName.Text);
objWriter.WriteLine("-------------------");
objWriter.WriteLine("Date of Birth: ");
objWriter.WriteLine(txt_Date.Text);*/
MessageBox.Show("SAVED");
}
}
}
Here's some very crappy code you can start from:
static void Main(string[] args)
{
string textBox1_Text = "";
string textBox2_Text = "";
string textBox3_Text = "";
var list1 = textBox1_Text.Split(Environment.NewLine.ToCharArray()).ToList();
var list2 = textBox2_Text.Split(Environment.NewLine.ToCharArray()).ToList();
var list3 = textBox3_Text.Split(Environment.NewLine.ToCharArray()).ToList();
var largestListSize = list1.Count > list2.Count ? list1.Count : list2.Count;
largestListSize = list3.Count > largestListSize ? list3.Count : largestListSize;
var sb = new StringBuilder();
for (int i = 0; i < largestListSize; i++)
{
var list1Line = list1.Count <= i ? list1[i] : string.Empty;
var list2Line = list1.Count <= i ? list2[i] : string.Empty;
var list3Line = list1.Count <= i ? list3[i] : string.Empty;
sb.AppendFormat(#"""{0}""\t""{1}""\t""{2}""", list1Line, list2Line, list3Line);
}
System.IO.File.WriteAllText("your_path", sb.ToString());
}
A simple answer would be something like this:
private void Button1Click(object sender, EventArgs e) {
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Title = "Save As";
saveFileDialog.Filter = "Text File (*.txt)|*.txt";
saveFileDialog.InitialDirectory = #"C:\";
if (saveFileDialog.ShowDialog() == DialogResult.OK) {
FileStream fs = new FileStream(saveFileDialog.FileName, FileMode.Create);
using (StreamWriter objWriter = new StreamWriter(fs)) {
for (int i = 0; i < GetMaxRows(); i++) {
objWriter.WriteLine("\"{0}\"\t\"{1}\"\t\"{2}\"", GetText(i, 0), GetText(i, 1), GetText(i, 2));
}
}
MessageBox.Show("SAVED");
}
}
private int GetMaxRows() {
return Math.Max(Math.Max(textBox1.Lines.Length, textBox2.Lines.Length), textBox3.Lines.Length);
}
private string GetText(int row, int textboxId) {
switch (textboxId) {
case 0:
return textBox1.Lines.Length > row ? textBox1.Lines[row] : string.Empty;
case 1:
return textBox2.Lines.Length > row ? textBox2.Lines[row] : string.Empty;
case 2:
return textBox3.Lines.Length > row ? textBox3.Lines[row] : string.Empty;
default:
throw new Exception("Not a valid id");
}
}
But it looks like you are trying to save this in tab separated format. And the problem is when you write: '20" monitor' into the field and you get a "-sign in the middle. Perhaps the tab is enough as a separator?
This answer is just to fix the problem you mention, getting text from all textboxes like your output file. But i think you should try to find a better way to do this (perhaps a datagrid as suggested), and then solve the problems with invalid characters. Example for saving from datagrid: Exporting from a dataset to a tab delimited file
There are easier ways to save to a tab seperated file even with text delimiters and support for escaping characters that are invalid.
But since i dont know how this is going to be used i am just giving you a simple answer to your question, hope it helps.
How can we read a text file column by column.
Check my new code: I can read the data row-wise using text.split (' ')
But how can be the file read as column wise? Lets assume that a file contains number of rows and columns but I was able to read the data/value horizontally. The code you see that below that's what I could execute!
SEE THE CODE BELOW:-
private void Form1_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string text = "";
text = textBox1.Text;
string[] arr = text.Split(' ');
textBox2.Text = arr[5];
textBox3.Text = arr[8];
}
private void button3_Click(object sender, EventArgs e)
{
string file_name = "c:\\Excel\\count.txt";
string txtline = "";
System.IO.StreamReader objreader;
objreader = new System.IO.StreamReader(file_name);
do
{
txtline = txtline + objreader.ReadLine() + "\r\n";
txtline = txtline + objreader.ReadToEnd() + "";
this.textBox1.Text = "subzihut";
}
while (objreader.Peek() != -1);
textBox1.Text = txtline;
objreader.Close();
}
private void button2_Click(object sender, EventArgs e)
{
textBox4.Text = textBox2.Text + " " + textBox3.Text;
}
}
}
A textfile contains a sequence of characters, delimited by newline characters and probably other characters which are used as delimiters (usually a comma or a semiciolon).
When you read a file you simply read this stream of characters. There are helper functions which read such a file line-by-line (using the newline character as a delimiter).
In plain .Net there are no methods which read column-by-column.
So you should:
read the file line by line
split each line into fields/columns using string.Split() at the separator character(s)
access only the columns of interest
You can simply read the file line by line, splitt the lines and do whatever you want.
var lines = File.ReadLines(#"c:\yourfile.txt");
foreach(var line in lines)
{
var values = line.Split(' ');
}
public string getColumnString(int columnNumber){
string[] lines = System.IO.ReadAllLines(#"C:\inputfile.txt");
string stringTobeDisplayed = string.Empty;
foreach(string line in lines) {
if(columnNumber == -1){ //when column number is sent as -1 then read full line
stringTobeDisplayed += line +"\n"
}
else{ //else read only the column required
string [] words = line.Split();
stringTobeDisplayed += word[columnNumber] +"\n"
}
}
return stringTobeDisplayed;
}
Maybe this will help you:
public static void ReadFile(string path)
{
List<string> Col1 = new List<string>();
List<string> Col2 = new List<string>();
List<string> Col3 = new List<string>();
using (StreamReader sr = new StreamReader(path))
{
while (sr.EndOfStream)
{
string header = sr.ReadLine();
var values = header.Split(' ');
Col1.Add(values[0]);
Col2.Add(values[1]);
Col3.Add(values[2]);
}
}
}
It's true that sometimes you just don't know where to start. Here are some pointers.
You'll have to read the whole file in, probably using something like a StreamReader.
You can parse the first row into column names. Use StreamReader.ReadLine() to get the first line and then do some simple string parsing on it.
You'll want to create some kind of class/object to store and access your data.
Once you have column names, continue to parse the following lines into the proper arrays.
Some here's a rough idea
using(StreamReader sr = new StreamReadeR("C:\\my\\file\\location\\text.csv"))
{
string header = sr.ReadLine();
List<string> HeaderColumns = new List<string>(header.split(" ", StringSplitOptions.RemoveEmptyEntires));
myModelClass.Header = HeaderColumns;
etc...
You might also consider making some kind of dictionary to access columns by header name and index.
I'm new to programming and face some difficulties. I hope to save the data I'm generating (a WPF DataGrid) into a text file.
This is what I currently have:
MainWindow.xaml.cs:
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
string fileName = #"D:\projects\PersonInfos\Files\PersonInfos_Copy.txt";
PersonInfosTable.ConvertToTXTFile(fileName);
}
PersonInfosTable.cs:
public void ConvertToTXTFile(string fileName)
{
StringBuilder sb = new StringBuilder();
System.Text.Encoding Output = null;
Output = System.Text.Encoding.Default;
foreach (PersonInfos personinfos in PersonInfoDetails)
{
if (PersonInfos.SelectCheckBox == true)
{
string line = String.Format("L§" + personinfos.FirstName + "§" + personinfos.LastName + "§");
sb.AppendLine(line);
StreamWriter file = new StreamWriter(fileName);
file.WriteLine(sb);
file.Close();
}
}
}
Unfortunately, this doesn't work. PersonInfosDetails is of type ObservationCollections<T> and SelectCheckBox is the check box selected by the user, and indicates which files the user wants to save.
Any ideas or suggestions? I'd appreciate your help so much and thank you so much for your time!
It is not clear what is the SelectCheckBox property. However, you need to move the writing part of your program outside the loop. Inside the loop just add every person info to your StringBuilder instance.
public void ConvertToTXTFile(string fileName)
{
StringBuilder sb = new StringBuilder();
System.Text.Encoding Output = System.Text.Encoding.Default;
foreach (PersonInfos personinfos in PersonInfoDetails)
{
// Collect every personinfos selected in the stringbuilder
if (personinfos.SelectCheckBox == true)
{
string line = String.Format("L§" + personinfos.FirstName + "§" + personinfos.LastName + "§");
sb.AppendLine(line);
}
}
// Now write the content of the StringBuilder all together to the output file
File.WriteAllText(filename, sb.ToString())
}
Have you tried How to: Write to a Text File (C# Programming Guide)?
Also, the code you've supplied won't work unless SelectCheckBox is a static property of the PersonInfos class. You'll probably have to change the if statement to
if (personInfos.SelectCheckBox == true)
{
// ...
}