Delete Duplicates From Text File Using Array - c#

This is my code but I'm not sure what to put in a certain area (see below) as I keep getting an error there. I am basically loading up a text file and then deleting any values that are repeated and then outputting the updated copy of the text file.
The text file looks like,
5
5
3
2
2
3
My code is
{
public partial class Form1 : Form
{
//Global Variable
int[] Original;
public Form1()
{
InitializeComponent();
}
//Exit Application
private void mnuExit_Click_1(object sender, EventArgs e)
{
this.Close();
}
//Load File
private void mnuLoad_Click_1(object sender, EventArgs e)
{
//Code to Load the Numbers From a File
OpenFileDialog fd = new OpenFileDialog();
//Open the File Dialog and Check If A File Was Selected
if (fd.ShowDialog() == DialogResult.OK)
{
//Open File to Read
StreamReader sr = new StreamReader(fd.OpenFile());
int Records = int.Parse(sr.ReadLine());
//Assign Array Sizes
Original = new int[Records];
//Go Through Text File
for (int i = 0; i < Records; i++)
{
Original[i] = int.Parse(sr.ReadLine());
}
}
}
private void btnOutput_Click(object sender, EventArgs e)
{
//Store Original Array
string Output = "Original \n";
//Output Original Array
for (int i = 0; i < Original.Length; i++)
{
Output = Output + Original[i] + "\n";
}
//Create TempArray
int[] TempArray = new int[Original.Length];
//Set TempArray Equal to Original Array
for (int i = 0; i < Original.Length; i++)
{
TempArray[i] = Original[i];
}
//Current Index
int Counter = 0;
//Loop Through Entire Array
for (int i = 0; i < TempArray.Length; i++)
{
for (int j = i + 1; j < TempArray.Length; j++)
{
//Replace Duplicate Values With '-1'
if (TempArray[i] == TempArray[j])
{
TempArray[j] = -1;
Counter++;
}
}
}
//Set Size of Original Array
Original = new int[Original.Length - Counter];
//Counter = 0;
//Remove -1 Values
//error begins here
for (int i = 0; i < Original.Length; i++)
{
for (int j = i + 1; j < Original.Length; j++)
{
//Set Original Array Equal to TempArray For Values Not Equal To '-1'
if (j != -1)
{
Original[j] = TempArray[j];
//Counter++;
}
}
}
//error ends here
//Final Output -- The New Array
Output = Output + "Original Without Duplicates\n";
for (int i = 0; i < Original.Length; i++)
{
Output = Output + Original[i] + "\n";
}
lblOutput.Text = Output;
}
}
}

I understand your logic, but wer'e all lazy programmers. You could simply use LINQ in order to prevent duplication. Load the array as you did already and use the Distinct method somthing like this:
int[] newArray = Orginal.Distinct().ToArray();
Goodluck.

Related

Creating a txt from listbox but without the last blank line

thanks for your help!
When creating a txt from a listbox, the txt is being generated with a last empty line here is my code:
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog lsd = new SaveFileDialog();
if (lsd.ShowDialog() == DialogResult.OK)
{
StreamWriter writer = new StreamWriter(lsd.FileName + ".TXT");
for (int i = 0; i < listBox1.Items.Count; i++)
{
writer.WriteLine(listBox1.Items[i]);
}
writer.Close();
}
lsd.Dispose();
}
Any Idea on how I can avoid generating that last line?
Thanks again for your help!
how about
for (int i = 0; i < listBox1.Items.Count; i++)
{
if(i == listBox1.Items.Count - 1 && listBox1.Items[i].Length == 0)
break;
writer.WriteLine(listBox1.Items[i]);
}
ie - if its the last line and its blank then ignore it
StreamWriter.WriteLine writes the text representation a span of characters to the string, followed by a line terminator. So, you can avoid generating the last line by using StreamWriter.Write for the last item.
int lastIndex = listBox1.Items.Count - 1;
for (int i = 0; i < lastIndex; i++)
{
writer.WriteLine(listBox1.Items[i]);
}
writer.Write(listBox1.Items[lastIndex]);
Reference.
private void button1_Click(object sender, EventArgs e)
{
if (listBox1.Items.Count < 1)
return;
using (SaveFileDialog lsd = new SaveFileDialog())
{
lsd.AddExtension = true;
lsd.DefaultExt = "txt";
lsd.Filter = "Text Files|*.txt";
if (lsd.ShowDialog() == DialogResult.OK)
{
using (StreamWriter writer = new StreamWriter(lsd.FileName))
{
int i;
for (i = 0; i < listBox1.Items.Count - 1; i++)
{
writer.WriteLine(listBox1.Items[i]);
}
writer.Write(listBox1.Items[i]);
}
}
}
}

C# String not printed on sameline StreamWriter issue

The follwoing code is used by me to print entires in a datagrid view into text file by converting them into strings! The data grid view has 3 columns(3rd column has several strings) and I want to print each data grid view row as a single line in the text file!
private void button1_Click_1(object sender, EventArgs e) // converting data grid value to single string
{
String file = " " ;
for (int i = 0; i < dataGridView2.Rows.Count; i++)
{
for (int j = 0; j < dataGridView2.Rows[i].Cells.Count; j++)
{
if (dataGridView2.Rows[i].Cells[j].Value != null)
{
if (j == 0)
{
file = Environment.NewLine + file + dataGridView2.Rows[i].Cells[j].Value.ToString();
}
else
{
file = file + dataGridView2.Rows[i].Cells[j].Value.ToString();
}
}
}
using (StreamWriter sw = new StreamWriter(#"C:\Users\Desktop\VS\Tfiles\file.txt"))
{
{
sw.Write(file);
}
}
}
}
Though a textfile is created the first 2 columns and the 1st string in the 3rd column are printed on the same line but the other strings of the 3rd column are printed on a new line! how can i get them onto the same line.
eg- let a sample data grid view row be like (aaa) (bbb) (ccc dddd eee) and it must appear in the textfile as aaa bbb ccc dddd eee but from my code it appears like aaa bbb ccc on the sameline, dddd on a new line and eee on another new line! how can i correct this issue?
Instead of relying on j==0, you can append new line outside of inner for loop. Also to put in that many string values you should really use StringBuilder. Try this:
private void button1_Click_1(object sender, EventArgs e) // converting data grid value to single string
{
StringBuilder file = new StringBuilder();
for (int i = 0; i < dataGridView2.Rows.Count; i++)
{
for (int j = 0; j < dataGridView2.Rows[i].Cells.Count; j++)
{
var val = dataGridView2.Rows[i].Cells[j].Value;
if (val == null)
continue;//IF NULL GO TO NEXT CELL, MAYBE YOU WANT TO PUT EMPTY SPACE
var s=val.ToString();
file.Append(s.Replace(Environment.NewLine," "));
}
file.AppendLine();//NEXT ROW WILL COME INTO NEXT LINE
}
using (StreamWriter sw = new
StreamWriter(#"C:\Users\Desktop\VS\Tfiles\file.txt"))
{
sw.Write(file.ToString());
}
}
EDIT:- Seems 3rd column contains strings with new line so we can remove the new line from string before putting to file:
var s = val.ToString();
file.Append(s.Replace(Environment.NewLine, " "));
Try this:
for (int i = 0; i < dataGridView2.Rows.Count; i++)
{
for (int j = 0; j < dataGridView2.Rows[i].Cells.Count; j++)
{
if (dataGridView2.Rows[i].Cells[j].Value != null)
{
file = file + dataGridView2.Rows[i].Cells[j].Value.ToString();
}
}

random uppercase in a word + multiple string insert

I really need a solution for the next scenario(I've been searching for hours and beating about the bushes to find a smooth solution, but none worked):
I have a winform that:
parse a text file
generate some folders using random words from that file
My code so far:
int value;
string path = null;
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog(this) == DialogResult.OK)
{
path = fbd.SelectedPath;
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
value = Convert.ToInt32(textBox1.Text);//store the value from the textbox in variable "value"
}
private void button2_Click(object sender, EventArgs e)
{
if (path != null && Directory.Exists(path))
for (int i = 0; i < value; i++)
{
Random rnd = new Random();
string tick1 = rnd.Next(0, 10).ToString();
var lines = File.ReadAllLines(#"M:\\dictionar.txt");
var r = new Random(DateTime.Now.Millisecond);
var randomLineNumber = r.Next(0, lines.Length - 1);
var line = lines[randomLineNumber];
StringBuilder b = new StringBuilder();
for (int j = 0; j < line.Length; j++)
{
char c = line[j];
if (rnd.Next(2) == 0)
{
c = Char.ToUpper(c);
}
b.Append(c);
if (j % 3 == 2)
{
b.Append(rnd.Next(10));
}
}
line = b.ToString();
Directory.CreateDirectory(Path.Combine(path, string.Format("{0}", line.Insert(2, tick1).Insert(4, tick1).Insert(6, tick1))));
}
}
Is there a way to use ToUpper() method as line.Insert() one so that I can get random upper letters? More, is there a better way of randomizing those index positions form line.Insert() (I'm asking this because when it's generating the folders name: the indexes are the same: e.g pe8rs8on8al and just after that the index changes.)?
I want to achieve the following:
if I have the next words in the .txt file:
personal
football
programming
computer
I would like the folder names to look like:
Pe3rs9oN1al
fO8ot5Ba6lL
You can loop through the characters in the string and build a new string depending on random values:
StringBuilder b = new StringBuilder();
for (int i = 0; i < line.Length; i++ ) {
char c = line[i];
if (rnd.Next(2) == 0) {
c = Char.ToUpper(c);
}
b.Append(c);
if (i % 2 == 1) {
b.Append(rnd.Next(10));
}
}
line = b.ToString();
Note: You shouldn't create Random objects in the loop. You should create a single Random object before the loop and use for all random numbers that you need. Creating instances too close in time will make them return the same sequences of random numbers. Also, you don't need to seed the random generator from the clock, the constructor without parameters does that automatically:
Random rnd = new Random();
So, the code in the method would be:
if (path != null && Directory.Exists(path))
Random rnd = new Random();
for (int i = 0; i < value; i++)
{
var lines = File.ReadAllLines(#"M:\\dictionar.txt");
var randomLineNumber = rnd.Next(0, lines.Length);
var line = lines[randomLineNumber];
StringBuilder b = new StringBuilder();
for (int j = 0; j < line.Length; j++)
{
char c = line[j];
if (rnd.Next(2) == 0)
{
c = Char.ToUpper(c);
}
b.Append(c);
if (j % 2 == 1)
{
b.Append(rnd.Next(10));
}
}
line = b.ToString();
Directory.CreateDirectory(Path.Combine(path, line));
}
}
Note the rnd.Next(0, lines.Length) to pick a random line. The upper limit for the random number is not inclusive, so if you use rnd.Next(0, lines.Length - 1) it will never pick the last line.
That's because you are specifying only tick1 in the same loop. If you want to change this, add additional ticks to your code as below:
string tick1 = rnd.Next(0, 10).ToString();
string tick2 = rnd.Next(0, 10).ToString();
string tick3 = rnd.Next(0, 10).ToString();
Then use those in your formatting of the string:
Directory.CreateDirectory(Path.Combine(path, string.Format("{0}", line.Insert(2, tick1).Insert(4, tick2).Insert(6, tick3))))
Like Guffa said you should not use Random in a loop, in all preference you should only instanciate one of it, but I think you could use it like this
public static class StringRandomize
{
static readonly Random rnd = new Random();
static char[] permmitedCharacters { get; set; }
static StringRandomize()
{
List<char> Chars= new List<char>();
for (int i = 48; i < 48+10; i++)
{
Chars.Add((char)i);
}
for (int i = 65; i < 65+26; i++)
{
Chars.Add((char)i);
}
permmitedCharacters = Chars.ToArray();
}
public static string Randomize(string input, double RandomizePercent = 30)
{
StringBuilder result = new StringBuilder();
int index = 0;
while (index < input.Length)
{
if (rnd.Next(0, 100) <= RandomizePercent)
{
if (rnd.Next(0, 100) <= RandomizePercent)
{
result.Append(GenerateCaracter());
}
else
{
if (rnd.Next(0, 100) > 50)
{
result.Append(input.ToLower()[index]);
}
else
{
result.Append(input.ToUpper()[index]);
}
index++;
}
}
else
{
result.Append(input[index]);
index++;
}
}
return result.ToString();
}
private static char GenerateCaracter()
{
return permmitedCharacters[rnd.Next(0, permmitedCharacters.Length)];
}
}
private static void GenerateRandomDirectories(string path, int value)
{
//I'm supposing value is the number of lines that you want
var lines = File.ReadAllLines(#"M:\\dictionar.txt");
Random rnd = new Random();
if (path != null && Directory.Exists(path))
{
for (int i = 0; i < value; i++)
{
Directory.CreateDirectory(path + "\\" + StringRandomize.Randomize(lines[rnd.Next(0,lines.Length)]));
}
}
}
"pers3o7Nal"
"foOtBaLl"
Got like this
public Form1()
{
InitializeComponent();
string content = "";
using (FileStream fs = new FileStream("D:\\names.txt", FileMode.Open, FileAccess.Read))
using (StreamReader sr = new StreamReader(fs))
content = sr.ReadToEnd();
string[] names = content.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
string path = "D:\\RandDirs";
if (!Directory.Exists(path))Directory.CreateDirectory(path) ;
for (int i = 0; i < 50; i++) Directory.CreateDirectory(path + "\\" + getRandomName(names));
}
Random randName = new Random();
Random insertingNumber = new Random();
Random randUpper = new Random();
Random randInsertNumber = new Random();
string getRandomName(string[] names)
{
string name = names[randName.Next(names.Length)];
name = name.Replace(" ", "");
string result = "";
for (int i = 0; i < name.Length; i++)
result += (randUpper.Next(0, 9) <= 5 ? name[i].ToString().ToLower() : name[i].ToString().ToUpper())
+ (((i + 1) % 2 == 0) ? insertingNumber.Next(0, 9).ToString() : "");
return result;
}
as per your needs, i've changed from randomly inserting numbers to inserting number every 2 characters.

How do I read extra lines of a text file in addition to my DataGridView?

private void open(object sender, EventArgs e)
{
// only works for opening the table
dataGridView1.Rows.Clear();
OpenFileDialog openDialog = new OpenFileDialog();
if (openDialog.ShowDialog() == DialogResult.OK)
{
fileLabel.Text = openDialog.FileName;
// Use File.ReadAllLines, it's easier
string[] lines = File.ReadAllLines(openDialog.FileName);
foreach (string line in lines)
{
var text = line.Split(',', '\n');
dataGridView1.Rows.Add(text);
}
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
dataGridView1.Rows[i].HeaderCell.Value = (i + 1).ToString();
}
}
}
This is currently my code for opening and reading. So I also have the writing code (actually I wrote a text file already) and I want to add in a few more pieces of information somewhere on the form but not on the dataGridView1
Now in my previous version I had the following code added for reading the extra lines of a text file.
int k = 0;
while (k < lines.Length)
{
for (int j = 0; j < twoDTextBox.GetLength(0); j++)
{
for (int i = 0; i < twoDTextBox.GetLength(1); i++)
{
statsBonus[j, i].Text = lines[k];
k++;
}
}
// these lines I would like to add to read in my new file
textBox1.Text = lines[k];
k++;
comboBox1.SelectedItem = lines[k];
k++;
checkBox1.Checked = Convert.ToBoolean(lines[k]);
k++;
}
Before I used to use textboxes but later found out it wasn't really efficient and dynamic.
So now how do I add the bottom lines to my form after reading the DataGridView lines?

Loading Data to a gridview

I have a DataGridView and I want to save its content to a CSV file. Then when I run the program again it loads the data from the CSV file to the gridview.
I have this code to save to CSV file:
private void button1_Click(object sender, EventArgs e)
{
FileInfo todel = new FileInfo(#"c:\dd\GB STOCK.csv");
todel.Delete();
int cols;
//open file
StreamWriter wr = new StreamWriter(#"c:\dd\GB STOCK.csv");
//determine the number of columns and write columns to file
cols = dataGridView1.Columns.Count;
for (int i = 0; i < cols ; i++)
{
wr.Write(dataGridView1.Columns[i].Name.ToString().ToUpper() + ",");
}
wr.WriteLine();
//write rows to excel file
for (int i = 0; i < (dataGridView1.Rows.Count - 1); i++)
{
for (int j = 0; j < cols; j++)
{
if (dataGridView1.Rows[i].Cells[j].Value != null)
{
wr.Write(dataGridView1.Rows[i].Cells[j].Value + ",");
}
else
{
wr.Write(",");
}
}
wr.WriteLine();
}
//close file
wr.Close();
}
And this code to load from the csv to the gridview:
private void Form1_Load(object sender, EventArgs e)
{
string rowValue;
string[] cellValue;
if (System.IO.File.Exists(#"C:\dd\GB STOCK.csv"))
{
System.IO.StreamReader streamReader = new StreamReader(#"C:\dd\GB STOCK.csv");
// Reading header
rowValue = streamReader.ReadLine();
cellValue = rowValue.Split(',');
for (int i = 0; i <= cellValue.Count() - 1; i++)
{
DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
column.Name = cellValue[i];
column.HeaderText = cellValue[i];
dataGridView1.Columns.Add(column);
}
// Reading content
while (streamReader.Peek() != -1)
{
rowValue = streamReader.ReadLine();
cellValue = rowValue.Split(',');
dataGridView1.Rows.Add(cellValue);
}
streamReader.Close();
}
else
{
MessageBox.Show("No File is Selected");
}
}
now the problem is that whenever I save and load the gridview it adds one extra column (without header) every time.
Could anybody tell me what is the wrong with this code?
When you save you are ending the line with a comma. So when the file gets read back in it thinks there is an extra (empty) value on the end. Try:
rowValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
While Saving the Data grid values to CSV, Check the Count of Grid view Column (How much its coming.? and How much column is actually.?) In Your button1_Click.
Carefully debug your code.
Have you tried Something like this in your button1_Click also:
`cols = dataGridView1.Columns.Count - 1;`
Or
for (int i = 0; i < cols - 1; i++)
{
wr.Write(dataGridView1.Columns[i].Name.ToString().ToUpper() + ",");
}

Categories