Writing text with a for cycle - c#

for (int i = 0; i<count; i++)
{
if (Herojai[i].Jėga == Herojai[i].Intelektas || Herojai[i].Jėga == Herojai[i].Vikrumas || Herojai[i].Intelektas == Herojai[i].Vikrumas)
{
string text = Herojai[i].Vardas; // (the thing I want to write)
File.WriteAllText(#"xxx.csv", text);
}
}
With this code, every loop where the if gets passed, the text gets overwritten for new one. I don't know how to write a new line in the CSV every loop.

var items = Herojai.Where(i => i.Jėga == i.Intelektas || i.Jėga == i.Vikrumas || i.Intelektas == i.Vikrumas)
.Select(i => i.Vardas);
using (var sw = new StreamWriter(#"xxx.csv"))
{
foreaach(var item in items)
{
sw.WriteLine(item);
}
}

In your case, I would use StringBuilder class to connected string values in If condition, then let all content write to a file.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++)
{
if (Herojai[i].Jėga == Herojai[i].Intelektas || Herojai[i].Jėga == Herojai[i].Vikrumas || Herojai[i].Intelektas == Herojai[i].Vikrumas)
{
sb.Append(Herojai[i].Vardas);
}
}
File.WriteAllText(#"xxx.csv", sb.ToString());

Use AppendAllText method:
File.AppendAllText(#"xxx.csv", text + Environment.NewLine);
Instead of:
File.WriteAllText(#"xxx.csv", text);

File.WriteAllText will open a file, write the text, and then close it. It will overwrite whatever is already in the file.

Related

How to read the text file line by line and save even numbering lines to **even.txt** and odd numbering lines to **odd.txt** in c#?

How to read the text file line by line and save even numbering lines to even.txt and odd numbering lines to odd.txt in c# ?
StreamReader dr=new StreamReader(#"C:\Users\Venkatesh\Desktop\sample.txt");
string ln=string.Empty;
int c = 0;
while (ln != null)
{
c += 1;
if (c%2 == 0){
StreamWriter even = new StreamWriter(#"C:\even.txt");
even.WriteLine(ln);
}
else {
StreamWriter odd = new StreamWriter(#"C:\odd.txt");
odd.WriteLine(ln);
}
}
Instead of opening/closing the output files in the loop, You can do it something like this...
using (var odd = File.CreateText("odd.txt"))
using (var even = File.CreateText("even.txt"))
{
int count = 0;
foreach (var line in File.ReadLines(filename))
{
(count++ % 2 == 0 ? even : odd).WriteLine(line);
}
}
What you want is something like this:
string ln = string.Empty;
int c = 0;
using (StreamWriter odd = new StreamWriter(#"C:\Users\rdaniel\Desktop\odd.txt"))
using (StreamWriter even = new StreamWriter(#"C:\Users\rdaniel\Desktop\even.txt"))
using (StreamReader dr = new StreamReader(#"C:\Users\rdaniel\Desktop\example.txt"))
{
while (ln != null)
{
ln = dr.ReadLine();
c += 1;
if (c % 2 == 0)
{
even.WriteLine(ln);
}
else
{
odd.WriteLine(ln);
}
}
}

Filtering elements of an array

I have an array as
That is, each item has its category in the following index.
I need all the items whose category are TotalNumbers and CurrentNumbers.
I tried
int i = 1;
foreach (string item in statsname)
{
//only number type stats are added to the comboboxes.
if ((statsname[i].ToUpperInvariant()==("TOTALNUMBER")) || ((statsname[i].ToUpperInvariant()==("CURRENTNUMBER"))))
{
comboBox1.Items.Add(statsname[i-1]);
i++;
i++;
}
comboBox1.SelectedIndex = 0;
}
Apparently this does not checks for what I need correctly.
How do I need to modify my codes to get what i need ?
Seems it's better to use a for loop instead of foreach:
for (int i = 1; i < statsname.Length; i += 2)
{
//only number type stats are added to the comboboxes.
if ((statsname[i].ToUpperInvariant()==("TOTALNUMBER")) || ((statsname[i].ToUpperInvariant()==("CURRENTNUMBER"))))
comboBox1.Items.Add(statsname[i-1]);
}
Linq comes to rescue!
var listItems = from s in statsname where s.Equals("TOTALNUMBER", StringComparison.InvariantCultureIgnoreCase) || s.Equals("CURRENTNUMBER", StringComparison.InvariantCultureIgnoreCase) select new ListItem(s);
comboBox1.AddRange(listItems);
Code not tested or compiled, but you can have an idea of what i said.
var filteredValues = Array.FindAll(source, s => s.ToUpperInvariant() == "TOTALNUMBER" ||
s.ToUpperInvariant() == "CURRENTNUMBER").ToList()
I am not sure why you are using index in an foreach loop. The below code should work for you
foreach (string item in statsname)
{
if ( item.ToUpper() == "TOTALNUMBER" || item.ToUpper() == "CURRENTNUMBER")
{
comboBox1.Items.Add(item);
}
}
comboBox1.SelectedIndex = 0;

How to write to csv file with StringBuilder ignoring the first row/line of CSV?

Since the first row of this CSV file already includes the column names, so I just want to ignore the first line and start to write from second line with StringBuilder.
StringBuilder sb = new StringBuilder();
foreach (DataRow dr in distinctValues.Rows)
{
vendor = dr.ItemArray[0].ToString();
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
if (vendor == ds.Tables[0].Rows[i]["VendorCode"].ToString())
{
for (int j = 0; j <= ds.Tables[0].Columns.Count - 1; j++)
{
if (j != 0)
sb.Append(",");
sb.Append(ds.Tables[0].Rows[i][ds.Tables[0].Columns[j]]);
}
sb.AppendLine();
}
}
File.WriteAllText(#csvFile, sb.ToString());
}
At last i understand that what i need is not to write a file but edit a file. so a changing of mind finally gives the answer.
File.AppendAllText is what i really need.
Try
File.AppendText("pathtofile")
or
FileMode.Append via FileStream
If the case of File.AppendText, all your calls to sb.AppendLine() would become sw.WriteLine() in the example below:
// This text is always added, making the file longer over time
// if it is not deleted.
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine("This");
sw.WriteLine("is Extra");
sw.WriteLine("Text");
}
Something like this?
class Program
{
private const string csv ="Header\r\nLine1\r\nLine2";
static void Main(string[] args)
{
StringReader reader = new StringReader(csv);
StringBuilder builder = new StringBuilder();
bool header = true;
while (true)
{
string line = reader.ReadLine();
if(header)
{
header = false;
continue;
}
if (line == null)
break;
builder.AppendLine(line);
}
Console.WriteLine(builder.ToString());
Console.ReadLine();
}
}
HTH

c# search string in txt file

I want to find a string in a txt file if string compares, it should go on reading lines till another string which I'm using as parameter.
Example:
CustomerEN //search for this string
...
some text which has details about the customer
id "123456"
username "rootuser"
...
CustomerCh //get text till this string
I need the details to work with them otherwise.
I'm using linq to search for "CustomerEN" like this:
File.ReadLines(pathToTextFile).Any(line => line.Contains("CustomerEN"))
But now I'm stuck with reading lines (data) till "CustomerCh" to extract details.
If your pair of lines will only appear once in your file, you could use
File.ReadLines(pathToTextFile)
.SkipWhile(line => !line.Contains("CustomerEN"))
.Skip(1) // optional
.TakeWhile(line => !line.Contains("CustomerCh"));
If you could have multiple occurrences in one file, you're probably better off using a regular foreach loop - reading lines, keeping track of whether you're currently inside or outside a customer etc:
List<List<string>> groups = new List<List<string>>();
List<string> current = null;
foreach (var line in File.ReadAllLines(pathToFile))
{
if (line.Contains("CustomerEN") && current == null)
current = new List<string>();
else if (line.Contains("CustomerCh") && current != null)
{
groups.Add(current);
current = null;
}
if (current != null)
current.Add(line);
}
You have to use while since foreach does not know about index. Below is an example code.
int counter = 0;
string line;
Console.Write("Input your search text: ");
var text = Console.ReadLine();
System.IO.StreamReader file =
new System.IO.StreamReader("SampleInput1.txt");
while ((line = file.ReadLine()) != null)
{
if (line.Contains(text))
{
break;
}
counter++;
}
Console.WriteLine("Line number: {0}", counter);
file.Close();
Console.ReadLine();
With LINQ, you could use the SkipWhile / TakeWhile methods, like this:
var importantLines =
File.ReadLines(pathToTextFile)
.SkipWhile(line => !line.Contains("CustomerEN"))
.TakeWhile(line => !line.Contains("CustomerCh"));
If you whant only one first string, you can use simple for-loop.
var lines = File.ReadAllLines(pathToTextFile);
var firstFound = false;
for(int index = 0; index < lines.Count; index++)
{
if(!firstFound && lines[index].Contains("CustomerEN"))
{
firstFound = true;
}
if(firstFound && lines[index].Contains("CustomerCh"))
{
//do, what you want, and exit the loop
// return lines[index];
}
}
I worked a little bit the method that Rawling posted here to find more than one line in the same file until the end. This is what worked for me:
foreach (var line in File.ReadLines(pathToFile))
{
if (line.Contains("CustomerEN") && current == null)
{
current = new List<string>();
current.Add(line);
}
else if (line.Contains("CustomerEN") && current != null)
{
current.Add(line);
}
}
string s = String.Join(",", current);
MessageBox.Show(s);

Finding 'pairs' in a List

I have a list of Buttons and I want to get the two elements that are 'equal':
for (int i = 0; i < Memory.Count; i++ )
{
piezas = Memory.FindAll(s => (s.Name != Memory[i].Name && Utilidades.CompareImage(s.Image, Memory[i].Image)));
}
This is supposed (if I'm not wrong) the list with the two elements that have different Name but are using the same Image. I'm more than sure that such elements exists... but I don't know why this doesn't work.
"Utilidades.CompareImage" is an static method:
public static bool CompareImage(Image firstImage, Image secondImage)
{
MemoryStream ms = new MemoryStream();
firstImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
String firstBitmap = Convert.ToBase64String(ms.ToArray());
ms.Position = 0;
secondImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
String secondBitmap = Convert.ToBase64String(ms.ToArray());
if (firstBitmap.Equals(secondBitmap))
return true;
else
return false;
}
I've tested the method before and it's working as intented.
Can you please help me?
The code
for (int i = 0; i < Memory.Count; i++ )
{
var piezas = Memory.FindAll(s => (s.Name != Memory[i].Name
&& Utilidades.CompareImage(s.Image, Memory[i].Image)));
}
creates a new 'piezas' every time and then doesn't use it.
Also you are checking all combinations twice.
So do you want to find all pairs, the first pair or maybe something in between?
A quick fix, but far from perfect,
for (int i = 0; i < Memory.Count; i++ )
{
var piezas = Memory.FindAll(s => (s.Name != Memory[i].Name
&& Utilidades.CompareImage(s.Image, Memory[i].Image)));
if (piezas.Count > 0)
{
// use piezas[0] somehow
break;
}
}
It seems no one mentioned SelectMany yet:
var pieza = Memory.SelectMany((m, i) =>
Memory.Where((m2, j) => i < j && m.Name != m2.Name &&
Utilidades.CompareImage(m.Image, m2.Image))
.Select(m2 => Tuple.Create(m, m2))).First();
if you want all pairs, not just one, replace the final First() call to ToList() or something like that.

Categories

Resources