First, a recommendation:
I would recommend using a free 3rd-party CSV library, rather than reinventing the wheel, unless there is some reason you can't.
http://joshclose.github.io/CsvHelper/
Now, the answer:
It sounds like your problem is how to handle empty cells. First, you need to make sure each row is the correct length, in a CSV you'll at least get a delimited between each cell, even if they're empty. (NOTE: I wrote all of this code long-hand without an IDE, it likely won't compile as-is, there may be errors).
var line = reader.ReadLine();
var values = line.Split(';');
if (values.Count != numColumnsExpected)
{
throw new System.Exception("Expected " + numColumnsExpected + " columns, only found " + values.Count + " columns for a row.");
}
Each column should have an expected type, you could have a validation and processing function for each column if you want to be thorough. You could map the column number to a function in a Dictionary.
private void ProcessorDelegate(string value);
Dictionary<int, ProcessorDelegate> m_processorMethods = new Dictionary<int, ProcessorDelegate>
{
{ 0, DateProcessor },
{ 1, PriceProcessor },
}
private void DateProcessor(string value)
{
// Make sure 'value' is a date
DateTime date;
if (!DateTime.TryParse(value, out date))
{
// If this field is required you could throw an exception here, or output a console error.
// This is the point at which you could check if 'value' was null or empty.
return;
}
// 'value' was a date, so add it to the DateTime[] array.
Dates.Add(date);
}
int numColumnsExpected = 6;
var Dates = new List<string>();
var Prices = new List<double>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
if (values.Count != numColumnsExpected)
{
throw new System.Exception("Expected " + numColumnsExpected + " columns, only found " + values.Count + " columns for a row.");
}
// Sanity check, you must have a processor for each column
if (values.Count > m_processorMethods.Count)
{
throw new System.Exception("Expected " + numColumnsExpected + " processor methods, only found " + m_processorMethods.Count);
}
for (int i = 0; i < values.Count; ++i)
{
// Pass the value for a column to the processor that handles
// data for that column.
m_processorMethods[i](values[i]);
}
}
DateTime[] s=Convert.ToDateTime(ListA.toArray());
double[] o=ListB.toArray();
object[,] PriceByDate=new object[,]{{s},{o}} ;
}
Warning:
Storing your data in a series of 2D arrays that are supposed to all map to one another by indices, is very fragile. Even storing it in a 2D object array isn't very useful because you'll need to cast those objects to make any use of them, and you'd need to know what data type each column was in order to cast them anyway.
I would highly recommend creating a class that holds the data for a row. Within that class you can store the date, price, and whatever other data you need. Then you can just have a List or array of those objects, each object representing a row.
public class RowObject
{
public DateTime date;
public string price;
}
List<RowObject> m_rowData;
// A delegate that can take the RowObject
private void ProcessorDelegate(string value, RowObject currentRow);
// Pass in the RowObject to your processors
// The processor updates the RowObject with the processed information.
private void DateProcessor(string value, RowObject currentRow)
{
// Make sure 'value' is a date
DateTime date;
if (!DateTime.TryParse(value, out date))
{
// If this field is required you could throw an exception here, or output a console error.
// This is the point at which you could check if 'value' was null or empty.
return;
}
// 'value' was a date, so set this row's date
currentRow.date = date;
}
Now all of your data for a row is tied together nicely, and if there are empty cells then that row's RowObject is missing that data. You could easily validate a row by adding a validation method to RowObject.
public class RowObject
{
public DateTime date;
public string price;
public bool IsValid()
{
if (date == null)
{
// Maybe output a warning to console here
return false;
}
if (string.IsNullOrEmpty(price))
{
// Maybe output a warning to console here
return false;
}
return true;
}
}
Finally
Let me reiterate that a lot of this in reinventing the wheel, if you use the CSVHelper library I provided a link to then you don't need most of this code.