I have a CSV file which contains four columns i.e Name, Surname, Age, Data of Birth
I want to change the column Name to FullName. How can this be done in c# please?
var reader = new StreamReader(File.OpenRead(#"C:\myCSV.csv"));
var line = reader.ReadLine();
var values = line.Split(';');
var title = line.Split(',');
Console.WriteLine(title[0]);
if (title.Contains("Name"))
{
title[0] = "FullName";
}
Now I'm stuck on how should I continue to change the Column name
If you are attempting to create a new file with 3 columns instead of 4 this would be a starting point, however, you should use a csv parser. This is just a demonstration to show you how to combine the two columns.
string[] lines = System.IO.File.ReadAllLines(#"C:\myCSV.csv");
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\myCSV2.csv"))
{
foreach (string line in lines)
{
if (line==lines[0])
{ //Change Header
file.WriteLine("Fullname,Age,Date of Birth");
}
else
{
string[] values = line.Split(',');
file.WriteLine(string.Format("{0} {1},{2},{3}",
values[0],values[1],values[2],values[3]));
}
}
}
Related
I'm trying to get a csv file into a data table but there are some things in the csv file that I am trying to omit from being entered into the data table, so I wrote it to a list first.
The csv files that i will using the software for have different sections in it for which I then split the whole list into the separate lists for those sections.
After all that was achieved, i needed to skip some lines in each list and wrote the final form i was happy with to lists respective to previous set of lists.
Now I hit a wall, I need to write each of the lists to a respective data grid.
public partial class Form1 : Form
{
String filePath = "";
//list set 1 = list box
List<String> lines = new List<String>();
List<String> accountList = new List<String>();
List<String> statementList = new List<String>();
List<String> summaryList = new List<String>();
List<String> transactionList = new List<String>();
//list set 2 = dgv
List<String> accountList2 = new List<String>();
List<String> statementList2 = new List<String>();
List<String> summaryList2 = new List<String>();
List<String> transactionList2 = new List<String>();
public Form1()
{
InitializeComponent();
}
private void btn_find_Click(object sender, EventArgs e)
{
try
{
using (OpenFileDialog fileDialog = new OpenFileDialog()
{ Filter = "CSV|* .csv", ValidateNames = true, Multiselect = false })
if (fileDialog.ShowDialog() == DialogResult.OK)
{
String fileName = fileDialog.FileName;
filePath = fileName;
}
try
{
if (File.Exists(filePath))
{
lines = File.ReadAllLines(filePath).ToList();
foreach (String line in lines)
{
String addLine = line.Replace("'", "");
String addLine2 = addLine.Replace("\"", "");
String str = line.Substring(0, 1);
int num = int.Parse(str);
if (addLine2.Length > 1)
{
String addLine3 = addLine2.Substring(2);
switch (num)
{
case 2:
accountList.Add(addLine3);
break;
case 3:
statementList.Add(addLine3);
break;
case 4:
summaryList.Add(addLine3);
break;
case 5:
transactionList.Add(addLine3);
break;
}
}
}
}
else
{
MessageBox.Show("Invalid file chosen, choose an appropriate CSV file and try again.");
}
transactionLB.DataSource = transactionList;
//var liness = transactionList;
//foreach (string line in liness.Skip(2))
// transactionList2.Add(line);
//Console.WriteLine(transactionList2);
//var source = new BindingSource();
//source.DataSource = transactionList2;
//trans_dgv.DataSource = source;
accountLB.DataSource = accountList;
summaryLB.DataSource = summaryList;
statementLB.DataSource = statementList;
}
catch (Exception)
{
MessageBox.Show("Cannot load CSV file, Ensure that a valid CSV file is selected and try again.");
}
}
catch (Exception)
{
MessageBox.Show("Cannot open File Explorer, Something is wrong :(");
}
}
}
EDIT 1:
the table has the following columns for the transaction lists (each of the lists have different columns) :
'Number' , 'Date' , 'Description1' , 'Description2' , 'Description3' , 'Amount' , 'Balance' , 'Accrued Charges'
an example of data in the lines of the transaction list:
9, 02 Sep, Petrol Card Purchase, Shell Kempton Park, 968143*7188 30 Aug, -714.45, -10661.88, 5.5
some liness do contain null values.
If I understand correctly, it seems like you're wanting to get the value of the strings in your string list to appear in your DataGridViews. This can be a little tricky because the DataGridView needs to know which property to display and strings only have the Length property (which probably isn't what you're looking for). There are a lot of ways to go about getting the data you want into the DataGridView. For example you could use DataTables and choose which column you want displayed in the DataGridView. If you want to stick with using string lists, I think you could get this to work by modifying your DataSource line to look something like this:
transactionLB.DataSource = transactionList.Select(x => new { Value = x} ).ToList();
I hope this helps! Let me know if I've misunderstood your question. Thanks!
my csv data is something looks like this:
Device data for period 30/08/2016 to 30/08/2016
Site ID,Time,INC1_MD
VSI-18,2016-08-30 00:00:00,165.954
VSI-18,2016-08-30 00:01:00,14.524
VSI-18,2016-08-30 00:02:00,32.920
VSI-18,2016-08-30 00:03:00,48.508
VSI-18,2016-08-30 00:04:00,62.418
.....
and I try to ignore first two line and start at "VSI-18..."
and extract third column data which is after the date & time column
and export them into new csv file, 1 column per day
like:
day1,day2,day3
100,200,300
200,123,123
123,222,444
....
and here is my code
o_csv_loc.Text = varFile; //csv data file location
save_file_loc.Text = saveloc; //new csv file location
var reader = new StreamReader(File.OpenRead(varFile));
List <string[]> listA = new List<string[]>();
List<string[]> listB = new List<string[]>();
List<string[]> listC = new List<string[]>();
//I think these two code below is to skip first 2 line of csv data
//file and start read the third line (VSI-18...)
reader.ReadLine();
reader.ReadLine();
while (reader.Peek() > -1)
{
var line = reader.ReadLine();
var values = line.Split(';');
listA.Add(new string[] { values[0] });
listB.Add(new string[] { values[1] });
listC.Add(new string[] { values[2] });
//I think that listC is suppose to extract the data after the
//second comma which is third column
}
for the export data code I not yet finish because I can't figure out how to read data yet.
when debug, 'System.IndexOutOfRangeException' show on line
listB.Add(new string[] { values[1] });
Isn't should not be problem on this line? values[0] is not problem yet.
EDIT
I success to export data to new csv file
var reader = new StreamReader(File.OpenRead(varFile));
List <string[]> listA = new List<string[]>(); //here are the code
//changed
List<string[]> listB = new List<string[]>();
List<string[]> listC = new List<string[]>();
reader.ReadLine();
reader.ReadLine();
while (reader.Peek() > -1)
{
var line = reader.ReadLine();
var values = line.Split(',');
listA.Add(new string[] { values[0] });
listB.Add(new string[] { values[1] });
listC.Add(new string[] { values[2]});
}
using (System.IO.TextWriter writer = File.CreateText(saveloc))
{
for (int index = 0; index < listC.Count; index++)
{
writer.WriteLine(string.Join(",", listC[index]) + ',');
}
}
result is this:
165.954,
14.524,
32.920,
48.508,
62.418,
79.151,
96.982,
I still figuring how to detect new date and put into new column
First, like one of the comments stated...in your code you're using ; as the delimiter character however the csv file is using ,...so the result of var values = line.Split(';'); is an aray with only one element.
Second, I would safeguard my application against incorrect formats or corrupted data. For example
var line = reader.ReadLine();
if(string.IsNullOrEmpty())//<--empty row
continue;//<--ignore, or else add empty values to your in-memory lists
var values = line.Split(',');
listA.Add(new string[] { values.length > 0 ? values[0] : string.Empty });
listB.Add(new string[] { values.length > 1 ? values[1] : string.Empty });
listC.Add(new string[] { values.length > 2 ? values[2] : string.Empty });
//or simply
if(values.length < 3)
continue;//<--ignore, or else add empty values to your in-memory lists
Few points.
You might be getting an error/exception due to delimiter (;) used doesn't actually split the string, so values[1] throws IndexOutOfRange exception . Use the correct delimiters (, what you need).
If your intention is to generate new csv (with same string) why do you need to split the string? can't we directly write it to file (assuming it is , delimited)?
var sb = new StringBuilder();
while (reader.Peek() > -1)
{
var line = reader.ReadLine();
sb.AppendLine(line);
}
// Write to file.
File.WriteAllText(filePath, sb.ToString());
I am trying to write a program for a school project that will read a csv file containing a name on each line and output each name and the number of times it occurrences in a list box. I would prefer for it not to be pre set for a specific name but i guess that would work also. So far i have this but now I'm stuck. The CSV file will have a name on each line and also have a coma after each name. Any help would be great thanks.
This is what I have so far:
string[] csvArray;
string line;
StreamReader reader;
OpenFileDialog openFileDialog = new OpenFileDialog();
//set filter for dialog control
const string FILTER = "CSV Files|*.csv|All Files|*.*";
openFileDialog.Filter = FILTER;
//if user opens file and clicks ok
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
//open input file
reader = File.OpenText(openFileDialog.FileName);
//while not end of stream
while (!reader.EndOfStream)
{
//read line from file
line = reader.ReadLine().ToLower();
//split values
csvArray = line.Split(',');
Using Linq we can do the following:
static IEnumerable<Tuple<int,string>> CountOccurences(IEnumerable<string> data)
{
return data.GroupBy(t => t).Select(t => Tuple.Create(t.Count(),t.Key));
}
Test:
var strings = new List<string>();
strings.Add("John");
strings.Add("John");
strings.Add("John");
strings.Add("Peter");
strings.Add("Doe");
strings.Add("Doe");
foreach (var item in CountOccurences(strings)) {
Console.WriteLine (String.Format("{0} = {1}", item.Item2, item.Item1));
}
John = 3
Peter = 1
Doe = 2
To use in your case:
string filePath = "c:\myfile.txt"
foreach (var item in CountOccurences(File.ReadAllLines(filePath).Select(t => t.Split(',').First())))
Console.WriteLine (String.Format("{0} = {1}", item.Item2, item.Item1));
you can use a dictionary, where you can store the occurrence of each Name:
Dictionary<string,int> NameOcur=new Dictionary<string,int>();
...
while (!reader.EndOfStream)
{
//read line from file
line = reader.ReadLine().ToLower();
//split values
csvArray = line.Split(',');
if (NameOcur.ContainsKey(csvArray[0]))
{
///Name exists in Dictionary increase count
NameOcur[csvArray[0]]++;
}
else
{
//Does not exist add with value 1
NameOcur.Add(csvArray[0],1);
}
}
Inside of my file i have:
2,Sam,500.00
6,Mike,400.00
8,Robert,156.00
3,Steve,100.85
9,Anderson,234.90
Order: ID, Name, Salary.
I am working on a CSV parser using C# TextFieldParser.
using (TextFieldParser parser = new TextFieldParser(path))
{
parser.TextFieldType = FieldType.Delimited;
And i use a Delimiter by comma
parser.SetDelimiters(",");
bool firstLine = true;
while (!parser.EndOfData)
{
string[] fields = parser.ReadFields();
if (firstLine)
{
foreach (var val in fields)
{
dt.Columns.Add(val);
}
firstLine = false;
continue;
}
dt.Rows.Add(fields);
How can i Sort the Data inside? Using Linq without using the function Split
var people = from line in File.ReadLines(path)
let parts = line.Split(delimiter)
select new Person {
Id = Int32.Parse(parts[0]),
Name = parts[1],
Salary = Decimal.Parse(parts[2])
};
Many Thanks
I am currently trying to merge some lines in a .csv file. The file follows a specific format which is split by "," and the last element uses \n ascii code. This means the last element gets put onto a new line and i return an array with only one Element. I am looking to merge this element with the line above it.
So my line would be:
192.168.60.24, ACD_test1,86.33352, 07/12/2014 13:33:13, False, Annotated, True,"Attribute1
Attribute 2
Attribute 3"
192.168.60.24, ACD_test1,87.33352, 07/12/2014 13:33:13, False, Annotated, True
Is it possible to merge/join the new line attributes with the line above?
My code is shown below:
var reader = new StreamReader(File.OpenRead(#path));
string line1 = reader.ReadLine();
if (line1.Contains("Server, Tagname, Value, Timestamp, Questionable, Annotated, Substituted"))
{
while (!reader.EndOfStream)
{
List<string> listPointValue = new List<string>();
var line = reader.ReadLine();
var values = line.Split(',');
if (values.Count() < 2)
{
//*****Trying to Add Attribute to listPointValue.ElememtAt(0) here******
}
else
{
foreach (string value in values)
{
listPointValue.Add(value);
}
allValues.Add(listPointValue);
}
}
// allValues.RemoveAt(0);
return allValues;
}
I think you want to read the next line before you do the allValues.Add. That way you can decide whether to add the previous line to allValues (starting a new line). This gives you an idea of what I mean:
var reader = new StreamReader(File.OpenRead(#path));
string line1 = reader.ReadLine();
if (line1.Contains("Server, Tagname, Value, Timestamp, Questionable, Annotated, Substituted"))
{
List<string> listPointValue = new List<string>();
// Add first line to listPointValue
var line = reader.ReadLine();
var values = line.Split(',');
foreach (string value in values)
{
listPointValue.Add(value);
}
while (!reader.EndOfStream)
{
// Read next line
line = reader.ReadLine();
values = line.Split(',');
// If next line is a full line, add the previous line and create a new line
if (values.Count() > 1)
{
allValues.Add(listPointValue);
listPointValue = new List<string>();
}
// Add values to line
foreach (string value in values)
{
listPointValue.Add(value);
}
}
allValues.Add(listPointValue);
}