I am getting an error use unassigned local variable 'multidimension' from below code. I am trying to put the data returned back from the text file in a multidimensional array by splitting them and put each row in in the array
private void button1_Click_1(object sender, EventArgs e)
{
string[,] Lines;
//string[][] StringArray = null;
//to get the browsed file and get sure it is not curropted
try
{
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
using (StreamReader sr = new StreamReader(openFileDialog1.FileName))
{
string[] data= null;
string ReadFromReadLine;
while ((ReadFromReadLine = sr.ReadLine()) != null)
{
data = ReadFromReadLine.Split(',');
for (int i = 0; i <= ReadFromReadLine.Length; i++)
{
for (int j = 0; j <= data.Length; j++ )
{
string[,] multidimensional;
multidimensional[i, j] = data[j];
}
}
}
//foreach(string s in Lines)
//{
// EditItemComboBox.Items.Add(s);
//}
}
FilePath.Text = openFileDialog1.FileName;
//textBox1.Text += (string)File.ReadAllText(FilePath.Text);
}
}
catch(IOException ex)
{
MessageBox.Show("there is an error" + ex+ "in the file please try again");
}
}
Any Ideas what I am doing wrong?
string[,] multidimensional;
should be:
string[,] multidimensional = new string[ReadFromReadLine.Length, data.Length];
and moved out of the for loops and maybe sent to a method, cached, or something
You are just defining an array called 'multidimensional', but not assigning it to anything.
for (int j = 0; j <= data.Length; j++ )
{
string[,] multidimensional = new String[i,data.Length]
multidimensional[i, j] = data[j];
}
However, I am not sure I am following what you are trying to do in the innermost loop. You are defining a new array called 'multidimensional' each time you are looping through the elements in data and the old data is lost each time.
If 'multidimensional' is suppose to contain the contents of the entire file, you need to define it outside of the first loop, but to use an array like you are, you need to know the number of lines in your file. If you are using C#2 or greater, a List<> would be a better choice
var list = new List<String[]>();
while ((ReadFromReadLine = sr.ReadLine()) != null)
{
data = ReadFromReadLine.Split(',');
list.Add(data);
}
Related
I need to read from a CSV file (separated via “;”) and a new file should be created containing the transposed (rotated) table:
my input file:
The tool shall be able to receive the filename of the table from the user and load the table to transpose the content.
The tool shall be able to save the transposed table in a new file with the filename of the input file and extended with “transposed” (“filename_transposed.csv”).
my Code
public void ReadCsv()
{
// open the file "data.csv" which is a CSV file with headers
using (CsvReader csv = new CsvReader(
new StreamReader("C:\\Users\\moki\\Downloads\\Input.csv"), true))
{
int fieldCount = csv.FieldCount;
string[] headers = csv.GetFieldHeaders();
while (csv.ReadNextRecord())
{
for (int i = 0; i < fieldCount; i++)
Console.WriteLine(string.Format("{0}\n{1}",
headers[0], csv[i]) );
}
}
Console.ReadLine();
my Result
Since we're providing answers...
using System;
using System.Collections.Generic;
using System.Linq;
namespace _51306985
{
class Program
{
static List<List<string>> listOfList = new List<List<string>>();
static int longestCol = 0;
static void Main(string[] args)
{
FillTheList("M:\\StackOverflowQuestionsAndAnswers\\51306985\\testdata.csv");
PadTheList();
SpitItBackOut();
SpitItOutToAFile("M:\\StackOverflowQuestionsAndAnswers\\51306985\\testdata.csv");
Console.ReadLine();
}
private static void SpitItOutToAFile(string v)
{
string newPath = $"{System.IO.Path.GetDirectoryName(v)}\\{System.IO.Path.GetFileNameWithoutExtension(v)}_Rotated{System.IO.Path.GetExtension(v)}";
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(newPath))
{
for (int i = 0; i < longestCol; i++)
{
string lineToWrite = string.Empty;
for (int b = 0; b < listOfList.Count; b++)
{
lineToWrite += $"{listOfList[b][i]},";
}
lineToWrite = lineToWrite.Substring(0, lineToWrite.Length - 1);//remove the hanging comma
if (lineToWrite != "")
{
sw.WriteLine(lineToWrite);
}
}
}
}
private static void SpitItBackOut()
{
for (int i = 0; i < longestCol; i++)
{
string lineToWrite = string.Empty;
for (int b = 0; b < listOfList.Count; b++)
{
lineToWrite += $"{listOfList[b][i]},";
}
lineToWrite = lineToWrite.Substring(0, lineToWrite.Length - 1);//remove the hanging comma
if (lineToWrite != "")
{
Console.WriteLine(lineToWrite);
}
}
}
private static void PadTheList()
{
foreach (List<string> item in listOfList)
{
while (item.Count < longestCol)
{
item.Add("");
}
}
}
private static void FillTheList(string v)
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(v))
{
string currentLine = string.Empty;
while ((currentLine = sr.ReadLine()) != null)
{
listOfList.Add(currentLine.Split(',').ToList());
if (listOfList.Last().Count > longestCol)
{
longestCol = listOfList.Last().Count;
}
}
}
}
}
}
Input Data
a1,b1,c1,d1,e1
a2,b2,c2,d2,e2
a3,b3,c3,d3,e3
a4,b4,c4,d4,e4
a5,b5,c5,d5,e5
a6,b6
a7,b7,c7,d7
a8,b8,c8
Output
a1,a2,a3,a4,a5,a6,a7,a8
b1,b2,b3,b4,b5,b6,b7,b8
c1,c2,c3,c4,c5,,c7,c8
d1,d2,d3,d4,d5,,d7,
e1,e2,e3,e4,e5,,,
There surely is a more efficient way but this is a easy to understand way I think:
1.) put the data into a datatable, e.g. like:
StreamReader sr1 = new StreamReader("C:\\Users\\moki\\Downloads\\Input.csv"); //create the streamreader to read the input .csv
DataTable mydata = new DataTable(); //create an empty DataTable.....
string[] arr; //....and an array in which you will store the elemnets of each line
int i = 0; //just a variable to help counting where you are in your data
bool mydatasetup = false; //a variable to check in the loop if you already added the necessary number of columns to the datatable
using (sr1)
{
while (sr1.EndOfStream == false) //read the whole file
{
string line = sr1.ReadLine(); //get a line from the file
if (line != null && line != String.Empty) //check if there is content in the line
{
arr = line.Split(';'); //split the line at each ";" and put the elements in the array
if(mydatasetup == false) //after reading the first line add as many columns to your datatable as you will need.....
{
for (int u = 0; u < arr.Length; u++)
{
mydata.Columns.Add();
}
mydatasetup = true; //...but only do this once (otherwise you wil have an unneccessary big datatable
}
mydata.Rows.Add(); //add a row in you datatable in which you will store the data of the line
for (int j = 0; j < arr.Length; j++) //go throught each element in your array and put it into your datatable
{
if (arr[j] != "")
{
mydata.Rows[i][j] = arr[j];
}
}
i = i + 1; //increase the counter so that the program knows it has to fill the data from the next line into the next row of the datatable
}
}
}
2.) Then you can loop through your datatable's columns and add each row's contents to a Stringbuilder (whereby you transpose your data) which you then save as a .csv:
StringBuilder sb = new StringBuilder(); //create a stringbuilder
for (int u = 0; u < mydata.Columns.Count; u++) //loop through the COLUMNS of your datatable....
{
for (int i = 0; i < mydata.Rows.Count; i++) //....but for each column go through each row in the datatable first
{
sb.Append(mydata.Rows[i][u].ToString()); // and add the elements to the stringbuilder - here the transposing is actually done
if (i < mydata.Rows.Count - 1) //add a deliminator after each element because you want a .csv as output again
{
sb.Append(';');
}
}
sb.AppendLine(); //add another line to your stringbuilder in which you will store the next column of your datatable
}
File.WriteAllText("C:\\Users\\moki\\Downloads\\Output.csv", sb.ToString()); //finally create the output .csv
You could of course combine these two steps.
Just in case, if anyone want to know how to do it using Cinchoo ETL with few lines of code,
string csv = #"A1;B1;C1;D1;E1
A2;B2;C2;D2;E2
A3;B3;C3;D3;E3
A4;B4;C4;D4;E4
A5;B5;C5;D5;E5
";
StringBuilder sb = new StringBuilder();
using (var p = ChoCSVReader.LoadText(csv)
.WithDelimiter(";")
.ThrowAndStopOnMissingField(false)
)
{
using (var w = new ChoCSVWriter(sb)
.WithDelimiter(";")
)
{
w.Write(p.Cast<ChoDynamicObject>().Transpose(false));
}
}
Console.WriteLine(sb.ToString());
Output:
A1;A2;A3;A4;A5
B1;B2;B3;B4;B5
C1;C2;C3;C4;C5
D1;D2;D3;D4;D5
E1;E2;E3;E4;E5
Is there a way to remove sections of a document where i can specify the beginning and ending tags?
i need a way that i can remove a section of the document by passing in both my start and end catches, (##DELETEBEGIN and ##DELETEEND)
for example i have this in my document:
Hello, welcome to this document
##DELETEBEGIN{Some values to check in the code}
Some text that will be removed if the value is true
##DELETEEND
Final Line
If you need to delete text from ##DELETEBEGIN to ##DELETEEND, where ##DELETEBEGIN is not at the beginning of a Paragraph and ##DELETEEND is not at the end of a Paragraph, this code should work.
DocX document = DocX.Load("C:\\Users\\phil\\Desktop\\text.docx");
bool flag = false;
List<List<string>> list1 = new List<List<string>>();
List<string> list2 = new List<string>();
foreach (Novacode.Paragraph item in document.Paragraphs)
{
//use this if you need whole text of a paragraph
string paraText = item.Text;
var result = paraText.Split(' ');
int count = 0;
list2 = new List<string>();
//use this if you need word by word
foreach (var data in result)
{
string word = data.ToString();
if (word.Contains("##DELETEBEGIN")) flag = true;
if (word.Contains("##DELETEEND"))
{
flag = false;
list2.Add(word);
}
if (flag) list2.Add(word);
count++;
}
list1.Add(list2);
}
for (int i = 0; i < list1.Count(); i++)
{
string temp = "";
for (int y = 0; y < list1[i].Count(); y++)
{
if (y == 0)
{
temp = list1[i][y];
continue;
}
temp += " " + list1[i][y];
}
if (!temp.Equals("")) document.ReplaceText(temp, "");
}
document.Save();
I have to give some credit to this post for looping through each word.
I think i have found a solution to this, at least it works for me, please let me know if there is anything i can do better:
the deleteCommand would be the ##DELETEBEGIN string and the deleteEndCommand would be the ##DELETEEND
private void RemoveSection(DocX doc, string deleteCommand, string deleteEndCommand)
{
try
{
int deleteStart = 0;
int deleteEnd = 0;
//Get the array of the paragraphs containing the start and end catches
for (int i = 0; i < doc.Paragraphs.Count; i++)
{
if (doc.Paragraphs[i].Text.Contains(deleteCommand))
deleteStart = i;
if (doc.Paragraphs[i].Text.Contains(deleteEndCommand))
deleteEnd = i;
}
if (deleteStart > 0 && deleteEnd > 0)
{
//delete from the paraIndex as the arrays will shift when a paragraph is deleted
int paraIndex = deleteStart;
for (int i = deleteStart; i <= deleteEnd; i++)
{
doc.RemoveParagraphAt(paraIndex);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Hello Everyone,
As shown in the above image I want to add the decimal numbers column wise from a text file to datagrid control.
Following is my code snippet
List<string> str = new List<string>();
String st = "";
int k = 0;
string[] s ;
//Path to write contents to text file
string filename = #"E:\Vivek\contentcopy\clientlist.txt";
Form.CheckForIllegalCrossThreadCalls = false;
OpenFileDialog ofd = new OpenFileDialog();
ofd.FileName = "";
ofd.ShowDialog();
st = ofd.FileName;
if (string.IsNullOrEmpty(ofd.FileName))
return;
string Name = "", No1 = "",No2="";
string[] lines = File.ReadAllLines(st).Where(sw => !string.IsNullOrWhiteSpace(sw)).ToArray();
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].Contains("VENTURA SECURITIES LIMITED (NSE F&O)")) continue;
if (lines[i].Contains("ALL EXCHANGES DERIVATIVES CLIENTWISE STATEMENT AS ON 16-05-2012")) continue;
if (lines[i].Contains("-------------------------------------------------------")) continue;
s = lines[i].Split(' ');
if (s[0] == "PARTY" || s[0] == "") continue;
int z;
Name = "";
for (z = 1; z < s.Length; z++)
{
if (s[z] == "") continue;
if (s[z].Contains('.'))
{
No1+=s[z]+" ";
No2 = No1 + " ";
}
else
{
Name += s[z];
str.Add(s[0]+" "+Name);
}
}
dataGridView1.Rows.Add();
dataGridView1.Rows[k].Cells[0].Value = s[0];
dataGridView1.Rows[k].Cells[1].Value = Name;
dataGridView1.Rows[k].Cells[2].Value = No1;
dataGridView1.Rows[k].Cells[3].Value = No2;
k++;
}
File.WriteAllLines(filename, str);
dataGridView1.ReadOnly = true;
}
The line No1=s[z] directly takes the last column values ie 46,123.19 and so on.I want to fetch each column from the text file and store it in a string variable and then assign it to the datagrid view
I hope my doubt is clear.If not please let me know
Here is the simplest Solution:
Add a DataGrid View to Form and add a Button:
private void button1_Click(object sender, EventArgs e)
{
ReadAndFileter();
}
private void ReadAndFileter()
{
try
{
using(System.IO.StreamReader reader = new System.IO.StreamReader("file.txt"))
{
string line;
string []array;
int rowcount= 0;
decimal number;
string[] separators = { "\t", " " };
int columnCount = 0;
while ((line = reader.ReadLine()) != null)
{
array = line.Split(separators, StringSplitOptions.RemoveEmptyEntries);
dataGridView1.Rows.Add();
foreach (string str in array)
{
if (Decimal.TryParse(str,out number))
{
dataGridView1.Rows[rowcount].Cells[columnCount++].Value = number;
}
}
rowcount++;
columnCount = 0;
}
}
}
catch (Exception ex)
{
}
}
The File Contents are:
Abc 20.122 69.33 0.00 693.25 0.00
def 36.20 96.20 1.15 69.56 8.96
And the final output:
Lets say, you have for lines in your test file, then u need to do following things:
Use StreamReader.ReadLine(), to read one line at time.
Spilt the line using split(' ') and store it in a array
Remove all the empty ones from the array
Now at index 2,3,4,5,6 of the resulting array will have the string equivalent of the decimal numbers.
Repeat this for each StreamReader.ReadLine()
Hope this will help.
Your problem is that you are overwriting No1 every time you read a string, which explains why you only get the last value. What you could do is either;
Append the string:
No1 += s[z] + " ";
Which will put all the values behind eachother, seperated by a whitespace.
Or, you could make a List<String> and add each value to the list, meaning you have them stored seperated:
List<String> values = new List<String>();
foreach(...)
{
if (s[z] == "") continue;
if (s[z].Contains('.'))
{
values.Add(s[z])
}
else
{
Name += s[z];
str.Add(s[0] + " " + Name);
}
}
You can thereafter loop through the list and add each value to a row. Considering your code piece;
int i = 2;
foreach(string value in values)
{
dataGridView1.Rows[k].Cells[i].Value = value;
i++;
}
This should work.
Hope this helps.
Here is edited code: but for future I must suggest to give a try at least..
private void ReadAndFileter1()
{
try
{
using (System.IO.StreamReader reader = new System.IO.StreamReader("file.txt"))
{
string line;
string[] array;
int rowcount = 0;
decimal number;
string[] separators = { "\t", " " };
int columnCount = 1;
string[] lines = File.ReadAllLines("file.txt");
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].Contains("VENTURA SECURITIES LIMITED (NSE F&O)")) continue;
if (lines[i].Contains("ALL EXCHANGES DERIVATIVES CLIENTWISE STATEMENT AS ON 16-05-2012")) continue;
if (lines[i].Contains("-------------------------------------------------------")) continue;
array = lines[i].Split(separators, StringSplitOptions.RemoveEmptyEntries);
if (array[0] == "PARTY" || array[0] == "") continue;
dataGridView1.Rows.Add();
foreach (string str in array)
{
if (Decimal.TryParse(str, out number))
{
dataGridView1.Rows[rowcount].Cells[columnCount++].Value = number;
}
}
dataGridView1.Rows[rowcount].Cells[0].Value = array[0];
rowcount++;
columnCount = 1;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Here it is:
static void Main(string[] args)
{
Decimal result;
string[] splitchar = new string[]{" "};
using(StreamReader reader = new StreamReader(#"C:\Users\Dell\Desktop\input.txt"))
{
while(!reader.EndOfStream)
{
string[] splittedArray = reader.ReadLine().Split(splitchar, StringSplitOptions.RemoveEmptyEntries).Where(x => Decimal.TryParse(x, out result)).ToArray();
// put your code here to get insert the values in datagrid
}
}
}
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
Not sure if am on the right track but I want to find a index id of an array and check if it's equal to another id then display a message. it not working for some reason.
int _findID = 1;
using (StreamReader reader = new StreamReader("textfile.txt"))
{
string line = reader.ReadLine();
while (line != null)
{
string[] array = {line};
for (int i = 0; i < array.Length; i++)
{
if (array[i] == findID)
{
MesssageBox.show("Line found!!")
}
}
}
}
Any help appreciated
try
if(int.Parse(array[i]) == findID)
instead of
if (array[i] == findID)
You have to convert your string representation of your number to a int and then compare both int's.
this is even shorter than iterating over an array which always has 1 element:
while (line != null) {
if(int.Parse(array[i]) == findID)
MesssageBox.Show("Line found!!")
}
EDIT
Try
int _findID = 1;
List<String> names = new List<string>()
using (StreamReader reader = new StreamReader("textfile.txt"))
{
string line = reader.ReadLine();
int lineCount = 0;
while (line != null)
{
lineCount++;
names.Add(line);
if (lineCount == _findID)
MessageBox.Show("Line found!!");
}
}
#user1285872: array.Length this will give array length 1 in your case when you check if (array[i] == findID) thi will be (0==findID) if the value of findID ==0 then message will show.
Your code has various problems:
First if the file is not empty you have an endless loop as you read the line once and always check the same line:
string line = reader.ReadLine();
while (line != null) {}
The array is always 1 item long as you create it in the loop itself.
But for the problem with the lineID, what exactly is the content of such a line?