I'm trying to save the contents of my listView.
But I'm having some issues with it. In my text file it will look like this:
ListViewItem: {1234};ListViewSubItem: {daily};ListViewSubItem: {Backup};ListViewSubItem: {Every 2 days at: 23:0};ListViewSubItem: {};ListViewSubItem: {}
But I don't like that it adds "ListViewItem:" and "ListViewSubItem:" etc with my data.. I just want those strings inside {}.
And here is my code:
FileStream file = new FileStream(dataFolder + "\\BukkitGUI\\schedule.txt", FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter sw = new StreamWriter(file);
foreach (ListViewItem listItem in listView1.Items)
{
sw.WriteLine(listItem + ";" + listItem.SubItems[1] + ";" + listItem.SubItems[2] + ";" + listItem.SubItems[3] + ";" + listItem.SubItems[4] + ";" + listItem.SubItems[5]);
}
sw.Close();
file.Close();
Any help on this?
EDIT: Image of my listView:
Your code does this:
foreach (ListViewItem listItem in listView1.Items)
{
sw.WriteLine(listItem + ";" + listItem.SubItems[1] + ";" + listItem.SubItems[2] + ";" + listItem.SubItems[3] + ";" + listItem.SubItems[4] + ";" + listItem.SubItems[5]);
}
This is doing the following:
foreach (ListViewItem listItem in listView1.Items)
{
string listItemString = listItem.ToString();
// etc.
}
What do you think the value of listItem.ToString() will be?
The default implementation of object.ToString() simply outputs the name of the type. The implementation for ListViewItem and ListViewSubItem apparently output the name of the type, plus the content of the item or subitem.
If you want something different output, then you need to do it yourself. Output listItem.Text and listItem.SubItems[n].Text instead.
Q: If your input data is in JSON format, perhaps your best bet is to get a JSON parser?
For example:
Parsing REST Services JSON Responses (C#): illustrates System.Runtime.Serialization.Json
Otherwise, if it's just a "funny format", look at the .Net TextFieldParser:
Parsing Text Files with the TextFieldParser Object
It's too long to post it as comment so I'll write an answer. I hope at least it will give you a good direction on one way to deal with it. In general you need some way to manipulate string. Many options comes to mind, but in your case I think that using regex or regular expressions is the best option since they are powerful, you have a clear criteria about what should go inside the .txt file and what not, and you work with relatively small amount of data so even though the regular expressions are considered slower than other options, in your case I think this won't be a problem.
Here is what I've tried - just created a static method (some sort of helper method) that will clean the string for you so that you get only the info you need. The method itself is :
public static string ParseListView(string ListViewText)
{
var regex = new System.Text.RegularExpressions.Regex("{.*?}");
var match = regex.Match(ListViewText);
return match.ToString().TrimStart('{').TrimEnd('}');
}
Pretty simple method. There's a lot of things that you can adjust if needed to work better for your case. For example I'm using regex.Match() which returns only the first match, but maybe you'll find regex.Matches() more suitable for you. There are also a lot of other options when you work with regular expressions in C# so be sure to check them out.
Then in you foreach loop you just:
foreach (ListViewItem listItem in listView1.Items)
{
sw.WriteLine(ParseListView(listItem) + ";" + ParseListView(listItem.SubItems[1]) + ";" + ParseListView(listItem.SubItems[2]) + ";" + ParseListView(listItem.SubItems[3]) + ";" + ParseListView(listItem.SubItems[4]) + ";" + ParseListView(listItem.SubItems[5]));
}
Of course this looks pretty ugly so the logic inside the foreach loop most probably can be improved but I think this will get you going.
Related
I'm trying to replace a bunch of consecutive
var: $("#var").val()
lines in my JS script with a simple loop in c# like this:
#foreach(var q in myList){
#(q.var + ": $('#" + q.var + "').val()," + Environment.NewLine);
}
But any symbol I try to pass (', \" or "") generates the html entity (&-#39; or &-quot;).
var: $("#var").val()
and JS errors.
With a view only solution, is it possible to fix this?
To have an official answer in this post (or for futur readers) I will put my comment as an answer, which seems to have resolved the issue.
What you should use is Html.Raw to print raw content.
#(q.var + Html.Raw(": $(\"#") + q.var + Html.Raw("\").val(),") + Environment.NewLine);
I have an ASP.Net WebAPI service that accepts OData queries. One of my controller methods accepts an ODataQueryOptions instance and applies it to an IQueryable instance. So far so good. Everything is working as planned.
Now, I have a specific need to obtain one of the key/value pairs from the OData query. For example, if I have two filters specified (someproperty eq 123 and otherproperty eq 456), how can I obtain one of the key/value pairs from the raw filter? I've looked at some of the ODataUriParser documentation, but it is really complicated and seems overkill. Isn't there an easier way to obtain simple key/value pairs, like I would from a normal QueryString?
EDIT: I've since put in some manual string parsing to accomplish what I needed, but that's obviously not ideal. Therefore, I'm putting up a bounty on this question. Hopefully someone has a simple solution to this!
There is an easy approach using regex where you convert your Odata query filter into key Value pair , regex found from this answer Here
string strRegex = #"(?<Filter>" +
"\n" + #" (?<Resource>.+?)\s+" +
"\n" + #" (?<Operator>eq|ne|gt|ge|lt|le|add|sub|mul|div|mod)\s+" +
"\n" + #" '?(?<Value>.+?)'?" +
"\n" + #")" +
"\n" + #"(?:" +
"\n" + #" \s*$" +
"\n" + #" |\s+(?:or|and|not)\s+" +
"\n" + #")" +
"\n";
your replacement string is something like,
string strReplace = #"${Resource}:${Value},"
Which gives you output like,
someproperty:123,otherproperty:456
Then convert that string into dictionary of your KeyValue parameter or however you want to consume it
public Dictionary<String, String> getKeyValue(String input)
{
return input.Split(',').ToDictionary(kv => kv.Split(':').First(), kv => kv.Split(':').Last());
}
wassup guys im new to C# coding and i did a search but couldn't find exactly what im looking for. So i have a couple of text-boxes which holds string elements and integers
what i want to do is when these boxes are filled in i want to send a summary of the email to client/customer but the format is whats getting me.
(first, one) are strings equaling different text-boxes
my code is:
emailCompseTask.Body = first + one + Enviroment.NewLine +
second + two + Enviroment.NewLine
and so on problem is which i send thru email it shows something like this:
computer service25.00
instead of:
computer service 25.00
is there a way to add spacing to make this more presentable? or even a better way perhaps thanks in advance guys
try this :
emailCompseTask.Body = first + one + " "+ second + two ;
body takes as HTML input, check here for more spacing option.
I'm a bit confused, but you just want to add some spacing in the output? Just throw some spaces in there like you would another variable.
first + " " + one + Environment.NewLine
+ second + " " + two + Environment.NewLine;
You can use a table
string tableRow = #"<tr>
<td>{0}</td>
<td>{1}</td>
</tr>";
string htmlTable = #"<table>
{0}
</table>";
string rows = "";
// Can do this in a loop
rows += string.Format(tableRow, first, one);
rows += string.Format(tableRow, first, one);
emailComseTask.Body = string.Format(htmlTable, rows);
what i'm basically trying to do is compare two HUGE text files and if they match write out a string, i have this written but it's extremely slow. I was hoping you guys might have a better idea. In the below example i'm comparing collect[3] splitfound[0]
string[] collectionlist = File.ReadAllLines(#"C:\found.txt");
string[] foundlist = File.ReadAllLines(#"C:\collection_export.txt");
foreach (string found in foundlist)
{
string[] spltifound = found.Split('|');
string matchfound = spltifound[0].Replace(".txt", ""); ;
foreach (string collect in collectionlist)
{
string[] splitcollect = collect.Split('\\');
string matchcollect = splitcollect[3].Replace(".txt", "");
if (matchcollect == matchfound)
{
end++;
long finaldest = (start - end);
Console.WriteLine(finaldest);
File.AppendAllText(#"C:\copy.txt", "copy \"" + collect + "\" \"C:\\OUT\\" + spltifound[1] + "\\" + spltifound[0] + ".txt\"\n");
break;
}
}
}
Sorry for the vagueness guys,
What I'm trying to do is simply say if content from one file exists in another write out a string(the string isn't important, merely the time to find the two comparatives is). collectionlist is like this:
Apple|Farm
foundlist is like this
C:\cow\horse\turtle.txt
C:\cow\pig\apple.txt
what i'm doing is taking apple from collectionlist, and finding the line that contains apple in foundlist. Then writing out a basic windows copy batch file. Sorry for the confusion.
Answer(All credit to Slaks)
string[] foundlist = File.ReadAllLines(#"C:\found.txt");
var collection = File.ReadLines(#"C:\collection_export.txt")
.ToDictionary(s => s.Split('|')[0].Replace(".txt",""));
using (var writer = new StreamWriter(#"C:\Copy.txt"))
{
foreach (string found in foundlist)
{
string[] splitFound = found.Split('\\');
string matchFound = Path.GetFileNameWithoutExtension(found);
string collectedLine;
if (collection.TryGetValue(matchFound,out collectedLine))
{
string[] collectlinesplit = collectedLine.Split('|');
end++;
long finaldest = (start - end);
Console.WriteLine(finaldest);
writer.WriteLine("copy \"" + found + "\" \"C:\\O\\" + collectlinesplit[1] + "\\" + collectlinesplit[0] + ".txt\"");
}
}
}
Call File.ReadLines() (.NET 4) instead of ReadAllLines() (.NET 2.0).
ReadAllLines needs to build an array to hold the return value, which can be extremely slow for large files.
If you're not using .Net 4.0, replace it with a StreamReader.
Build a Dictionary<string, string> with the matchCollects (once), then loop through the foundList and check whether the HashSet contains matchFound.
This allows you to replace the O(n) inner loop with an O(1) hash check
Use a StreamWriter instead of calling AppendText
EDIT: Call Path.GetFileNameWithoutExtension and the other Path methods instead of manually manipulating strings.
For example:
var collection = File.ReadLines(#"C:\found.txt")
.ToDictionary(s => s.Split('\\')[3].Replace(".txt", ""));
using (var writer = new StreamWriter(#"C:\Copy.txt")) {
foreach (string found in foundlist) {
string splitFound = found.Split('|');
string matchFound = Path.GetFileNameWithoutExtension(found)
string collectedLine;
if (collection.TryGetValue(matchFound, collectedLine)) {
end++;
long finaldest = (start - end);
Console.WriteLine(finaldest);
writer.WriteLine("copy \"" + collectedLine + "\" \"C:\\OUT\\"
+ splitFound[1] + "\\" + spltifound[0] + ".txt\"");
}
}
}
First I'd suggest normalizing both files and putting one of them in a set. This allows you to quickly test whether a specific line is present and reduces the complexity from O(n*n) to O(n).
Also you shouldn't open and close the file every time you write a line:
File.AppendAllText(...); // This causes the file to be opened and closed.
Open the output file once at the start of the operation, write lines to it, then close it when all lines have been written.
You have a cartesian product, so it makes sense to index one side instead of doing an enhaustive linear search.
Extract the keys from one file and use either a Set or SortedList data structure to hold them. This will make the lookups much much faster. (Your overall algorithm will be O(N lg N) instead of O(N**2) )
I am new to programming. Is there a way to create multiple .txt files using
data from another file in C#.
like this:
1. we have data.txt with 100 or more strings
string1
string2
string3
...
2. we have textbox1 and textbox2 waiting for user to enter strings
3 . we need to create 100 or more files using strings from data.txt and textboxes strings: name of the fisrt file : string1+textbox1string.txt
and inside it we write:
textbox2string + string1 + textbox1string
the same pattern to create other files, second - string2+textbox1string.txt and inside second - textbox2string + string2 + textbox1string
sorry for my english i am not native speaker.
Well, it sounds like you want something like:
string[] lines = File.ReadAllLines("file1.txt");
foreach (string line in lines)
{
File.WriteAllText(line + textbox1.Text + ".txt",
textbox2.Text + line + textbox1.Text);
}
Basically for very simple tasks like this, the methods in the File class allow "one shot" calls which read or write whole files at a time. For more complicated things you generally have to open a TextReader/TextWriter or a Stream.
If this wasn't what you were after, please provide more information. Likewise if you find the code hard to understand, let us know and we'll try to explain. You may fine it easier with more variables:
string[] lines = File.ReadAllLines("file1.txt");
foreach (string line in lines)
{
string newFile = line + textbox1.Text + ".txt";
string fileContent = textbox2.Text + line + textbox1.Text;
File.WriteAllText(newFile, fileContent);
}
EDIT: If you want to add a directory, you should use Path.Combine:
string newFile = Path.Combine(directory, line + textbox1.Text + ".txt");
(You can do it just with string concatenation, but Path.Combine is a better idea.)
Look into the static File class. It will have a lot of what you want.
http://msdn.microsoft.com/en-us/library/6ka1wd3w.aspx
Sure...
string textbox1string = textbox1.Text, textbox2string = textbox2.Text;
foreach(string line in File.ReadAllLines("data.txt")) {
string path = Path.ChangeExtension(line + textbox1string, "txt");
File.WriteAllText(path, textbox2string + line + textbox1string);
}