I'm new to C# and writing this application that displays a message if the given name in the TextBox is in the popular list file. My book gives very little help to fix this, my error is the inputfile of if(boy.Contains(boyinputFile)) same for the girl where it says something about:
cannot convert to string.
private void checkName_Click(object sender, EventArgs e)
{
string boy;
string girl;
girl = girlBox.Text;
boy = boyBox.Text;
StreamReader boyinputFile;
StreamReader girlinputFile;
boyinputFile = File.OpenText("BoyNames.txt");
girlinputFile = File.OpenText("GirlNames.txt");
while (!boyinputFile.EndOfStream)
{
if (boyBox.Text.Contains(boyinputFile))
{
MessageBox.Show("Yes, your name is popular!");
}
}
while (!girlinputFile.EndOfStream)
{
if (girl.Contains(girlinputFile))
{
MessageBox.Show("Yes, your name is popular!");
}
else
{
MessageBox.Show("Sorry, couldn't find your name.");
}
}
boyinputFile.Close();
girlinputFile.Close();
}
You need to convert your stream to a string. This is where you are getting your error:
cannot convert to string
string girl_file = streamReader.ReadToEnd();
You then need to see if the selected name is within the string file. You need to reverse your check. You are checking to see if the textbox contains the file.
if (girl_file.Contains(girl))
{
MessageBox.Show("Yes, your name is popular!");
}
Also have a look at this question How do I convert StreamReader to a string?
I want to give you better code than the existing answers show you.
var lines = File.ReadAllLines("...");
var isMatch = lines.Contains(name);
It really can be that simple.
Try this:
string boy = boyBox.Text;
using (StreamReader sr = new StreamReader("D:\\BoyNames.txt"))
{
string boyinputFile = sr.ReadToEnd();
if (boyinputFil.Contains(boy))
{
MessageBox.Show("Yes, your name is popular!");
}
else
{
MessageBox.Show("Sorry, couldn't find your name.");
}
}
Replace this line
if (boyBox.Text.Contains(boyinputFile))
with
if (boyBox.Text.Contains(boyinputFile.ToString())).
Related
I write codes to receive the path of a text file and store it in a string variable that I declare in public.
Then I want to know if the file exists or not by using
System.IO.File.Exists(pathoffile)
But it always returns false even though there is a file.
And then when I try to add the string path directly like this
public string propertyfile = #"C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt"
The function
System.IO.File.Exists(pathoffile)
return true
I already check the receive path(string) that I read from the text file. By cutting off "\n" and "\r" and using trim() too.But it still returns false.
Have I missed something? What difference between these two?. I'm too new to this c#. I'm very bad at this sorry in advance.
Here are my codes
public string pathfromread, partnumber, pathfile, portname, partnofromserial,propertypathfile; //Declare Variables
public string propertyfile = #"C:\Users\PFA Wongsawat\Desktop\Properties.txt";
public string pathoffile ;
public string backuppath ;
public string pdffolderpath ;
private void propertyget()
{
if (File.Exists(propertyfile))
{
StreamReader readpropertyfile = new StreamReader(propertyfile);
string readproperty;
while ((readproperty = readpropertyfile.ReadLine()) != null)
{
string[] propertyfromread = readproperty.Trim().Split('=');
if (propertyfromread.GetValue(0).ToString() == "pathoffile")
{
pathoffile = propertyfromread.GetValue(1).ToString();
pathoffile = pathoffile.Replace("\n", "").Replace("\r", "");
MessageBox.Show(pathoffile, "path file");
}
else if ((propertyfromread.GetValue(0).ToString() == "backuppath"))
{
backuppath = propertyfromread.GetValue(1).ToString();
backuppath = backuppath.Replace("\n", "").Replace("\r", "");
MessageBox.Show(backuppath);
}
else if ((propertyfromread.GetValue(0).ToString() == "pdffolderpath"))
{
pdffolderpath = propertyfromread.GetValue(1).ToString();
pdffolderpath = pdffolderpath.Replace("\n", "").Replace("\r", "");
MessageBox.Show(pdffolderpath);
}
else if ((propertyfromread.GetValue(0).ToString() == "portname"))
{
portname = propertyfromread.GetValue(1).ToString();
portname = portname.Replace("\n", "").Replace("\r", "");
MessageBox.Show(portname);
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
propertyget();
dv = dt.DefaultView; //set dv index count to != 0 to prevent error from null input when click on remove button
if (System.IO.File.Exists(pathoffile))//Check if file exist or not
{
}
else
{
try
{
MessageBox.Show("Database Text File Missing. Please Select New File", "Database Text File Missing", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
OpenFileDialog regispath = new OpenFileDialog();
regispath.Title = "Select Database Text File (part_no_and_path_list.txt)";
regispath.Multiselect = false;
regispath.Filter = "Text file (*.txt)|*.txt";
regispath.RestoreDirectory = true;
regispath.ShowDialog();
pathfile = regispath.FileName;
File.Copy(pathfile, pathoffile);
}
catch
{
And this is my property text file
pathoffile=#"C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt"
backuppath=#"C:\Users\PFA Wongsawat\Documents\part_no_and_path_list.txt"
pdffolderpath=#"C:\Users\PFA Wongsawat\Downloads\"
portname=COM3
In this case the result always a messageBox showing "Database Text File Missing. Please Select New File"
Thank you and sorry for my bad English.
You don't put #" and " in the text file, you only put them in the code because that's how the c# compiler knows they're strings (and knows not to interpret slashes as an escape character)
Just make your text file look like:
pathoffile=C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt
I also recommend you use:
Split(new []{'='}, 2)
This will allow you to use = in your path, by making split return a maximum of 2 split values; any = that are legitimately in the path would be preserved
Actually I recommend you use one of the various built in settings mechanisms that c# has; we haven't needed to read and write our own configuration files for about 25 years
If you really do want to continue rolling your own you can reduce your code massively by using a dictionary
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class Settings{
private Dictionary<string,string> _conf = new Dictionary<string,string>();
public string PathOfFile {
get => _conf["pathoffile"];
}
public void ReadConfig(){
File.ReadAllLines("conf.txt").ToDictionary(
x => x.Split(new[]{'='},2)[0],
x => x.Split(new[]{'='},2)[1]
);
}
}
Yep, it's all you need. Every time you want to add another setting, add another property (like public string PathOfFile), add another love to the file and make sure the string in the property matches the line in the file
In other areas, please read up on c# naming conventions; PublicThingsAreNamedLikeThis, _privateLikeThis, localLikeThis, neverlikethis
Thank you I've already solved this problem
By remove "#" and '""' from path in the property text file like this.
pathoffile=C:\Users\PFA Wongsawat\Desktop\part_no_and_path_list.txt
backuppath=C:\Users\PFA Wongsawat\Documents\part_no_and_path_list.txt
pdffolderpath=C:\Users\PFA Wongsawat\Downloads\
portname=COM3
The reason I can't see this because I debug the program by seeing the result in message box and it not match with the real one. Thank you.
so i am trying to read text from a txt file and then add the text in to a custom class list,
the code is
public static List<BookInfo> LoadCSVFile(string fileName, out string qError)
{
qError = "";
fileName = "books.txt";
List<BookInfo> Book_Info = new List<BookInfo>();
StreamReader read = null;
try
{
read = new StreamReader(fileName);
while (!read.EndOfStream)
{
string line = read.ReadLine();
string[] values = line.Split(',');
if (values.Length == 3)
{
string Title = values[0].Trim();
string Author = values[1].Trim();
string ISBN = values[2].Trim();
try
{
Book_Info.Add(new BookInfo(Title, Author, ISBN));
}
catch (Exception ex)
{
qError = ex.Message;
return null;
}
}
else
{
qError = $"line {line} was unable to be read";
return null;
}
}
}
catch
{
qError = $"failed to open file: {fileName}";
return null;
}
finally
{
if (read != null)
{
read.Close();
}
}
if (qError == "")
{
return Book_Info;
}
return null;
}
once i have read the text it will be displayed in a form which i believe to be coded correctly
i have placed an error message in to show when the file has been read and each time i try something new the same error appears.
have i gone wrong somewhere when reading the txt file?
Edit:
Text file was created using visual studio and is in the same solution, text file is in bin/debug
I totally agree with thegeneral's answer, but to answer your initial question I suspect your books.txt file was not located in your Bin/Debug folder. I did test your code ;-P
Some notes
if you are going to use something that Implements IDisposable, it's always good practice to use the using statement
If this is only a small file, why bother with StreamReader when you can just use File.ReadAllLines
Linq is your friend, projection is a wonderful thing.
If you really want to parse a CSV file, I'd seriously consider a dedicated CSV parser library (like CsvHelper). It will save you many headaches
This is not really the bastion of perfect coding, however I tried to work with what you had and the spirit of what you were trying to do.
Some code:
public static List<BookInfo> LoadCSVFile(string fileName, out string qError)
{
try
{
// read all lines in to another type
// just makes it easier for errors which you seem to want
var lines = File.ReadAllLines(fileName)
.Select(x => new { Values = x.Split(','), Text = x })
.ToList();
// get a list of errors,
var errors = lines.Where(x => x.Values.Length != 3)
.Select((s, i) => $"Bad book! Line {i} : {s.Text}");
// return some errors
qError = string.Join(Environment.NewLine, errors);
// project lines to your books
return lines.Where(x => x.Values.Length == 3)
.Select(x => new BookInfo(x.Values[0], x.Values[0], x.Values[0]))
.ToList();
}
catch (Exception e)
{
qError = e.Message;
}
return null;
}
Disclaimer
I wouldn't usually catch errors like this, it's rather nasty
The whole anonymous type and returning errors is a bit smelly, if the file is corrupt, I'd just throw a big nasty exception and be done with it. Make the user do the right thing
This is going to fail the second you have a title with a comma in it
This is completely untested!
public class QuoteGenerator
{
public static randomQuote()
{
string t = "Quotes.txt";
List<string> Quotes = new List<string>();
using (StreamReader quoteReader = new StreamReader(t))
{
string line = "";
while ((line = quoteReader.ReadLine()) != null)
{
Quotes.Add(line);
}
}
string[] response = Quotes.ToArray();
string[] shuffle = Classes.RandomStringArrayTool.RandomizeStrings(response);
return (shuffle[0]);
}
}
Here's what's working and I thought my StreamReader code above would work the same:
public string randomQuote()
{
string[] response = new string[] {"The fortune you seek, is in another bot"
, "Someone has Googled you recently"
, "This fortune no good. Try another"
, "404 fortune not found"};
string[] shuffle = Classes.RandomStringArrayTool.RandomizeStrings(response);
return shuffle[0];
}
I need to return the first line of quote from the StreamReader Method, how come the code I put together doesn't seem to work? I've thought about hard-coding the quotes but maybe it's a good idea to save them in a text file. I guess I don't understand how using StreamReader work. Can anyone please explain, I've only been coding since July. Thank you!
Assuming your Quotes.txt file is in the bin directory the StreamReader code works fine. The only thing obvious is that you are not specifying a return type for the randomQuote method.
public static string randomQuote()
I been having trouble trying to figure this out. When I think I have it I get told no. Here is a picture of it.
I am working on the save button. Now after the user adds the first name, last name and job title they can save it. If a user loads the file and it comes up in the listbox, that person should be able to click on the name and then hit the edit button and they should be able to edit it. I have code, but I did get inform it looked wackey and the string should have the first name, last name and job title.
It is getting me really confused as I am learning C#. I know how to use savefiledialog but I am not allowed to use it on this one. Here is what I am suppose to be doing:
When the user clicks the “Save” button, write the selected record to
the file specified in txtFilePath (absolute path not relative) without
truncating the values currently inside.
I am still working on my code since I got told that it will be better file writes records in a group of three strings. But this is the code I have right now.
private void Save_Click(object sender, EventArgs e)
{
string path = txtFilePath.Text;
if (File.Exists(path))
{
using (StreamWriter sw = File.CreateText(path))
{
foreach (Employee employee in employeeList.Items)
sw.WriteLine(employee);
}
}
else
try
{
StreamWriter sw = File.AppendText(path);
foreach (var item in employeeList.Items)
sw.WriteLine(item.ToString());
}
catch
{
MessageBox.Show("Please enter something in");
}
Now I can not use save or open file dialog. The user should be able to open any file on the C,E,F drive or where it is. I was also told it should be obj.Also the program should handle and exceptions that arise.
I know this might be a noobie question but my mind is stuck as I am still learning how to code with C#. Now I have been searching and reading. But I am not finding something to help me understand how to have all this into 1 code. If someone might be able to help or even point to a better web site I would appreciate it.
There are many, many ways to store data in a file. This code demonstrates 4 methods that are pretty easy to use. But the point is that you should probably be splitting up your data into separate pieces rather than storing them as one long string.
public class MyPublicData
{
public int id;
public string value;
}
[Serializable()]
class MyEncapsulatedData
{
private DateTime created;
private int length;
public MyEncapsulatedData(int length)
{
created = DateTime.Now;
this.length = length;
}
public DateTime ExpirationDate
{
get { return created.AddDays(length); }
}
}
class Program
{
static void Main(string[] args)
{
string testpath = System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "TestFile");
// Method 1: Automatic XML serialization
// Requires that the type being serialized and all its serializable members are public
System.Xml.Serialization.XmlSerializer xs =
new System.Xml.Serialization.XmlSerializer(typeof(MyPublicData));
MyPublicData o1 = new MyPublicData() {id = 3141, value = "a test object"};
MyEncapsulatedData o2 = new MyEncapsulatedData(7);
using (System.IO.StreamWriter w = new System.IO.StreamWriter(testpath + ".xml"))
{
xs.Serialize(w, o1);
}
// Method 2: Manual XML serialization
System.Xml.XmlWriter xw = System.Xml.XmlWriter.Create(testpath + "1.xml");
xw.WriteStartElement("MyPublicData");
xw.WriteStartAttribute("id");
xw.WriteValue(o1.id);
xw.WriteEndAttribute();
xw.WriteAttributeString("value", o1.value);
xw.WriteEndElement();
xw.Close();
// Method 3: Automatic binary serialization
// Requires that the type being serialized be marked with the "Serializable" attribute
using (System.IO.FileStream f = new System.IO.FileStream(testpath + ".bin", System.IO.FileMode.Create))
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
bf.Serialize(f, o2);
}
// Demonstrate how automatic binary deserialization works
// and prove that it handles objects with private members
using (System.IO.FileStream f = new System.IO.FileStream(testpath + ".bin", System.IO.FileMode.Open))
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
MyEncapsulatedData o3 = (MyEncapsulatedData)bf.Deserialize(f);
Console.WriteLine(o3.ExpirationDate.ToString());
}
// Method 4: Manual binary serialization
using (System.IO.FileStream f = new System.IO.FileStream(testpath + "1.bin", System.IO.FileMode.Create))
{
using (System.IO.BinaryWriter w = new System.IO.BinaryWriter(f))
{
w.Write(o1.id);
w.Write(o1.value);
}
}
// Demonstrate how manual binary deserialization works
using (System.IO.FileStream f = new System.IO.FileStream(testpath + "1.bin", System.IO.FileMode.Open))
{
using (System.IO.BinaryReader r = new System.IO.BinaryReader(f))
{
MyPublicData o4 = new MyPublicData() { id = r.ReadInt32(), value = r.ReadString() };
Console.WriteLine("{0}: {1}", o4.id, o4.value);
}
}
}
}
As you are writing the employee objects with WriteLine, the underlying ToString() is being invoked. What you have to do first is to customize that ToString() methods to fit your needs, in this way:
public class Employee
{
public string FirstName;
public string LastName;
public string JobTitle;
// all other declarations here
...........
// Override ToString()
public override string ToString()
{
return string.Format("'{0}', '{1}', '{2}'", this.FirstName, this.LastName, this.JobTitle);
}
}
This way, your writing code still keeps clean and readable.
By the way, there is not a reverse equivalent of ToSTring, but to follow .Net standards, I suggest you to implement an Employee's method like:
public static Employee Parse(string)
{
// your code here, return a new Employee object
}
You have to determine a way of saving that suits your needs. A simple way to store this info could be CSV:
"Firstname1","Lastname 1", "Jobtitle1"
" Firstname2", "Lastname2","Jobtitle2 "
As you can see, data won't be truncated, since the delimiter " is used to determine string boundaries.
As shown in this question, using CsvHelper might be an option. But given this is homework and the constraints therein, you might have to create this method yourself. You could put this in Employee (or make it override ToString()) that does something along those lines:
public String GetAsCSV(String firstName, String lastName, String jobTitle)
{
return String.Format("\"{0}\",\"{1}\",\"{2}\"", firstName, lastName, jobTitle);
}
I'll leave the way how to read the data back in as an exercise to you. ;-)
I have looked all over for this. It could be me just typing the wrong thing in search I'm not sure. So, if you know a good tutorial or example of this please share. I'm trying to learn.
I have a C# Windows Form app I'm working on. I have information (movies in this case) saved in an XML file. I saved the xml file like this.
//Now we add new movie.
XmlElement nodRoot = doc.DocumentElement;
string allMyChildren = nodRoot.InnerText;
string capitalized = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(movieEditNameTextbox.Text);
int indexLookForNewMake = allMyChildren.IndexOf(capitalized);
if (indexLookForNewMake >= 0)
{
MessageBox.Show("Movie is already saved.", "Error");
}
else
{
XmlElement el = doc.CreateElement("Name");
el.InnerText = capitalized;
doc.DocumentElement.AppendChild(el);
//Check if Year is really a Number.
if (movieEditYearTextbox.Text.All(Char.IsDigit))
{
//Remove ' cause it gives errors.
string capitalizedFixed = capitalized.Replace("'", "");
string capitalizedFinalFixed = capitalizedFixed.Replace("\"", "");
//Assign Attribute to each New one.
el.SetAttribute("Name", capitalizedFinalFixed);
el.SetAttribute("Type", movieEditTypeDropdown.Text);
el.SetAttribute("Year", movieEditYearTextbox.Text);
//Reset all fields, they don't need data now.
movieEditNameTextbox.Text = "";
movieEditYearTextbox.Text = "";
movieEditTypeDropdown.SelectedIndex = -1;
removeMovieTextbox.Text = "";
doc.Save("movie.xml");
label4.Text = "Movie Has been Edited";
loadXml();
}
else
{
//Error out. Year not a Number
MessageBox.Show("Check movie year. Seems it isn't a number.", "Error");
}
}
That all works fine. Now what I'm trying to do is make it where you can choose a directory, and it search the directory and sub directories and get file names and save them into the XML file.
I used this to try to accomplish this. It does pull the list. But it doesn't save it. It don't save the new information.
I can't use LINQ as it cause a confliction for some reason with other code.
DirectoryInfo dirCustom = new DirectoryInfo(#"D:\Video");
FileInfo[] filCustom;
filCustom = dirCustom.GetFiles("*",SearchOption.AllDirectories);
//Open XML File.
XmlDocument doc = new XmlDocument();
doc.Load("movie.xml");
XmlElement el = doc.CreateElement("Name");
string fulCustoms = filCustom.ToString();
foreach (FileInfo filFile in filCustom)
{
string capitalized = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(filFile.Name);
string capitalizedFixed = capitalized.Replace("\"", "");
el.SetAttribute("Name", capitalizedFixed);
el.SetAttribute("Type", "EDIT TYPE");
el.SetAttribute("Year", "EDIT YEAR");
richTextBox1.AppendText(capitalizedFixed + "\r\n");
}
doc.Save("movie.xml");
label4.Text = "Movie Has been Edited";
loadXml();
Now, the richTextBox does display the information correctly but it don't save it.
The loadXml() is just my noobish way to refresh the datagridview.
I'm completely lost and don't know where to turn to. I know my coding is probarely horrible, lol. I'm new to this. This is my first more complex application I have worked on.
I can't think of anymore information that would help you understand what I mean. I hope you do.
Thank you so much for your help.
Not sure exactly what your LoadXML() method does but my only piece of advise with your issue is to change the way you are implementing this functionality.
Create an object called Movie
public class Movie
{
public Movie() {}
public String Title { get; set; }
blah... blah...
}
Then create a MovieList
public class MovieList : List<Movie> { }
Then implement the following 2 methods inside the MovieList.
public static void Serialize(String path, MovieList movieList)
{
XmlSerializer serializer = new XmlSerializer(typeof(MovieList));
using (StreamWriter streamWriter = new StreamWriter(path))
{
serializer.Serialize(streamWriter, movieList);
}
}
public static MovieList Deserialize(String path)
{
XmlSerializer serializer = new XmlSerializer(typeof(MovieList));
using (StreamReader streamReader = new StreamReader(path))
{
return (MovieList) serializer.Deserialize(streamReader);
}
}
Thats it... You now have your object serialized and you can retrieve the data to populate through binding or whatever other methods you choose.