Read a CSV file into an array in C#


Read a CSV file

The following LoadCsv method reads the CSV file into a two-dimensional array of strings.

// Load a CSV file into an array of rows and columns.
// Assume there may be blank lines but every line has
// the same number of fields.
private string[,] LoadCsv(string filename)
{
    // Get the file's text.
    string whole_file = System.IO.File.ReadAllText(filename);

    // Split into lines.
    whole_file = whole_file.Replace('\n', '\r');
    string[] lines = whole_file.Split(new char[] { '\r' },
        StringSplitOptions.RemoveEmptyEntries);

    // See how many rows and columns there are.
    int num_rows = lines.Length;
    int num_cols = lines[0].Split(',').Length;

    // Allocate the data array.
    string[,] values = new string[num_rows, num_cols];

    // Load the array.
    for (int r = 0; r < num_rows; r++)
    {
        string[] line_r = lines[r].Split(',');
        for (int c = 0; c < num_cols; c++)
        {
            values[r, c] = line_r[c];
        }
    }

    // Return the values.
    return values;
}

The code uses System.IO.File.ReadAllText to read the file’s contents into a string. It then uses Split to break the file into lines, ignoring any blank lines.

The code then loops through the lines using Split to split the lines into fields and adding their values to the array. When it’s done, the method returns the two-dimensional array of strings.

When you click the Go button, the following code calls the LoadCsv method and displays the result in a DataGridView control.

// Read the CSV file.
// Assumes each line has the same number of fields
// and no line is blank.
private void btnGo_Click(object sender, EventArgs e)
{
    // Get the data.
    string[,] values = LoadCsv(txtFile.Text);
    int num_rows = values.GetUpperBound(0) + 1;
    int num_cols = values.GetUpperBound(1) + 1;

    // Display the data to show we have it.

    // Make column headers.
    // For this example, we assume the first row
    // contains the column names.
    dgvValues.Columns.Clear();
    for (int c = 0; c < num_cols; c++)
        dgvValues.Columns.Add(values[0, c], values[0, c]);

    // Add the data.
    for (int r = 1; r < num_rows; r++)
    {
        dgvValues.Rows.Add();
        for (int c = 0; c < num_cols; c++)
        {
            dgvValues.Rows[r - 1].Cells[c].Value = values[r, c];
        }
    }
}

This code calls LoadCsv and saves the returned strings in an array. It uses the array’s GetUpperBound method twice to see how many rows and columns it contains.

Next the program clears the DataGridView control’s columns. It loops through the first values in each of the array’s columns and uses it to build a column in the DataGridView. For each value, it creates a column named after the value and displaying the value as its header text.

Next the code loops through the remaining rows in the table. For each row, it adds the row’s values to the DataGridView control’s cells.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in files, strings and tagged , , , , , , , , , , , . Bookmark the permalink.

140 Responses to Read a CSV file into an array in C#

  1. Michel Despatie says:

    Could not display the last (longitude) column. Had to modify the C< num_cols; to C<= num_cols; and r

  2. Rod Stephens says:

    Oops! The problem is in the code that displays the values. Instead of this:

    int num_rows = values.GetUpperBound(0);
    int num_cols = values.GetUpperBound(1); 

    It should have used this:

    int num_rows = values.GetUpperBound(0) + 1;
    int num_cols = values.GetUpperBound(1) + 1; 

    The number of rows (and columns) in an array is 1 more than the upper bound.

    Thanks for pointing this out!

  3. Cartoons says:

    Nice blog. Your code helped me out at work.

  4. Adrian says:

    Rather than two statements with “replace” and “split” it may be slightly quicker to use:

    string[] lines = whole_file.Split(new char[] { ‘\r’, ‘\n’ },
    StringSplitOptions.RemoveEmptyEntries);

  5. Habeeb says:

    My favourite csv parser is one built into .net library. This is a hidden treasure inside Microsoft.VisualBasic namespace.
    Below is a sample code:

    using Microsoft.VisualBasic.FileIO;
    
    // Habeeb, "Dubai Media City, Dubai"
    var path = @"C:\Person.csv";
    using (TextFieldParser csvParser = new TextFieldParser(path))
    {
        csvParser.CommentTokens = new string[] { "#" };
        csvParser.SetDelimiters(new string[] { "," });
        csvParser.HasFieldsEnclosedInQuotes = true;
         
        // Skip the row with the column names
        csvParser.ReadLine();
         
        while (!csvParser.EndOfData)
        {
            // Read current line fields,
            // pointer moves to the next line.
            string[] fields = csvParser.ReadFields();
            string Name = fields[0];
            string Address = fields[1];
        }
    }

    More details about the parser is given here: http://codeskaters.blogspot.ae/2015/11/c-easiest-csv-parser-built-in-net.html

    • Alexey says:

      No treasure, very slow. If you ever tried to read any csv excel sheet of 50 mb , you wouldnt never use this stub.

      • RodStephens says:

        “No treasure” is a bit harsh. I never said this could read a 50 MB file. 😉

        This method reads the whole file into a big string and then processes it. For a big file, that will take a lot of memory and will be slow. If you need to read a file that big, you’ll probably be better off using another method such as processing it in a stream. You might even try loading it into Excel or reading it and converting it into a new format such as XML, which loads much more quickly.

  6. Sandhya R says:

    I am a few days old in C#.
    I am expected to read a .csv file, which contains numbers, into a two dimensional array. Can u please tell me how to do it?
    Thank you for the help!

    • RodStephens says:

      This example should work. The only difference is that your values are numbers and this example works with strings. Simply use int.Parse, double.Parse, or a similar Parse method for your data type to convert the strings into numbers.

      • Sandhya R says:

        i tried this code as it is, with one change:

        var filePath = @”C:\MatlabPDNA\csvlist.csv”;
        // Get the data.
        string[,] values = LoadCsv(filePath);

        this is the error i get
        The name ‘dgvValues’ does not exist in the current context

        please help

        • RodStephens says:

          dgvValues would be a DataGridView control that the program is trying to use to display the values.

          If you just want to load the values into an array and not display them in a DataGridView, remove the code in the btnGo_Click event handler after the comment that says, “Display the data to show we have it.”

      • Sandhya R says:

        Sir, as a beginner i find your code to be complex.

        This is my code, it prints the numbers in a particular column from .csv file

        Console.WriteLine(“Prints a particular COLUMN”);
        reader = new StreamReader(filePath);
        while (!reader.EndOfStream)
        {
        line = reader.ReadLine();
        var values = line.Split(‘,’);
        Console.WriteLine(values[6]);
        // prints the values in 7th column
        }
        Console.ReadLine();

        how can i alter this code to convert the string in each column to a number and store them all in a 2D array.
        I code everything in main. I have not been exposed to functions and classes in c#. This is my first program. Please bear with me. Thank you very much.

        • RodStephens says:

          Sorry but, yes, some of the examples assume you have some previous experience.

          You should use the code in the LoadCsv method. All that method does it open the file and copy the values into the values array.

          You can copy that code into your main method. Or better yet, read about methods so you can just call LoadCsv. You would do it like this in your main method:

          string[,] values = LoadCsv(filename)

          Where filename is a variable holding the name of the file. Or you could make it a constant like “C:\\wherever\\values.csv.”

          To use numbers instead of strings, change the arrays to int[,] instead of string[,]. Then when the LoadCsv code saves a value, use int.Parse to convert it into an integer as in:

          values[r, c] = int.Parse(line_r[c]);

  7. J.claude says:

    hello sir ,
    how to remove empty row in array list?
    thanks!!!

    • RodStephens says:

      This line of code:

      string[] lines = whole_file.Split(new char[] { '\r' },
          StringSplitOptions.RemoveEmptyEntries);

      Should remove any lines that are completely empty. If you want to also remove lines that contain two empty values separated by a comma, that will take a bit more work.

      One approach would be to add the rows to a List instead of an array. Then you can skip any rows that don’t contain any data.

      Another approach would be to create the lines array as before. Then loop through it and count the rows that have data. Use the count to size the values array.

      Next loop through the entries and add them to the values array, skipping any that don’t contain data.

      All in all, quite a bit of extra work.

  8. s . chits says:

    hello sir. where in the code do i convert the array to an integer.

    • RodStephens says:

      This example reads the values as strings. You can either:

      1. Write another method that converts the array of strings into an array of integers

      2. Use integers instead of strings and then change this line:

      values[r, c] = line_r[c];

      Into this:

      values[r, c] = int.Parse(line_r[c]);
  9. DWalker07 says:

    The LoadCSV module code does a Split on the comma character. That doesn’t handle commas within quoted fields.

    • RodStephens says:

      True. Handling quoted fields that may contain commas is a bit more involved than simply using Split.

      To handle that situation, keep track of whether a quoted field is open. Create a character variable quote. When the first character in a field is a ” or ‘, set quote equal to that character. After that the field extends until you find a matching close quote.

      Habeeb’s suggestion of using a TextFieldParser might handle this for you.

  10. ameet says:

    Great Blog !!!!

    How can I calculate SUM on specific column I have same csv file and I want to calculate sum, as per your previous comment I tried” values[r, c] = int.Parse(line_r[c]); ” But getting Error Can not convert implicitly ……. ! Please tell me how to do it in a proper way.
    Thanks in advance.

    • RodStephens says:

      That looks like the right approach. You should check (possibly in the debugger) to see what value is in line_r[c] when you get the error. If it’s not an integer, then you would get problems. You may need to clean up the data or add code to check for that.

  11. Joe Pallagi says:

    hello Sir,
    I straggling on an issue for hours i cant find how to accomplish to whole column’s values in a single array, if you know the solution i would really really really appreciate 😀

    have fun!

    • RodStephens says:

      I don’t know if I understand what you need. Do you want to read the values from one column into an array instead of reading the whole page? If so, try using the code above with this loop:

      // Allocate the array for column col_num.
      string[] values = new string[num_rows];
      
      // Load the array.
      for (int r = 0; r < num_rows; r++)
      {
          string[] line_r = lines[r].Split(',');
          values[r] = line_r[col_num];
      }
  12. yen says:

    mine appeared just in one column instead of the two-dimensional array. please help

    • RodStephens says:

      Make sure you have the code correct. For example, if your data uses a different delimiter instead of commas, then it would put all of the values on a line in the first column.

  13. yen says:

    hi sir,
    thanks…secondly the string[,] values contains all sorts of data types…
    1. i need to use them individually with their own data types.
    2 for example putting them in a list
    3. I also want to put different items there into different variables inside different classes
    4. how can i store it in a dictionary

    thanks

    • RodStephens says:

      You can use Parse methods such as int.Parse and float.Parse to convert text values into other data types. You can use TryParse if you’re not sure whether a value has the right format.

      After you convert the items into the right data types, you should be able to save them in lists, arrays, variables, members of a class, etc.

  14. yen says:

    sir,
    Thank you very much for your good help.
    Assuming there are many columns such as:
    (i) subjects, (ii) classroom, and (iii) finished time……means that there are many subjects different classrooms and all the associated times. Subjects, classrooms and finished time can appear multiple times throughout the array.
    Please how do I search through the an array [ , ] to know which particular classroom corresponds to the last finished time for a particular subject.
    Please which approach and method can be used for this?
    many thanks
    yen.

  15. yen says:

    Also is it possible to parse a whole column array [1,N] at once without having to loop through each element one by one?

    • RodStephens says:

      You can either loop through the array or use LINQ. LINQ code is shorter so it’s easier to debug, but you need to learn a bit about LINQ to use it so that can make getting started a bit harder.

      If I were you, I would use LINQ. It can essentially look through a column and find the latest date/time, add up a column, and do just about anything for the values in one or more columns.

  16. yen says:

    Sir,
    Please kindly give me a simple example for using Linq to query the .csv file/array[N,N] and then send the result to a class.
    thanks

    • RodStephens says:

      If the data is in an string[,] then try something like this (without LINQ):

      private class ValuePair
      {
          public int X, Y;
      }
      
      private void Form1_Load(object sender, EventArgs e)
      {
          // Load some values.
          string[,] values =
          {
              {"A", "1", "1"},
              {"B", "2", "22"},
              {"C", "3", "333"},
          };
      
          // Loop through the array building the results.
          List pairs = new List();
          for (int i = 0; i < = values.GetUpperBound(0); i++)
          {
              int x = int.Parse(values[i, 1]);
              int y = int.Parse(values[i, 2]);
              ValuePair new_pair = new ValuePair() { X = x, Y = y };
              pairs.Add(new_pair);
          }
      
          // Convert the list into an array.
          ValuePair[] results = pairs.ToArray();
      
          // Display the results.
          for (int i = 0; i < results.Length; i++)
              Console.WriteLine(
                  results[i].X + ", " + results[i].Y);
      }
  17. yen says:

    Happy new year. Thank you very much.

  18. yen says:

    Please how can you show a 3 dimensional array in a DataGridView.
    thanks

  19. yen says:

    OK, Many thanks.
    Let me make it simpler, I am trying to load the data below into a 3 dimensional list/Jagged array. e.g converting [21, 7] into [x, y, z]
    where:
    x -there are just two dates for x but different dimensions -1st column
    y -this varies
    z -there are just two flights for z different dimensions -2nd column

    final output will be :
    2 pages:
    page 1: 5×5
    2×5
    and
    page 2: 5×5
    7×5

    Date flight from Start time to finish time distance(km)
    01/01/2017 FLI 101 country 1 2pm country 7 3pm 1000
    01/01/2017 FLI 101 country 2 4pm country 8 5pm 1500
    01/01/2017 FLI 101 country 3 9am country 9 10am 1000
    01/01/2017 FLI 101 country 4 12noon country 10 1pm 1500
    01/01/2017 FLI 101 country 5 10am country 11 11am 2000
    01/01/2017 FLI 102 country 6 1pm country 12 2pm 1000
    01/01/2017 FLI 102 country 7 4pm country 1 5pm 1000
    02/01/2017 FLI 101 country 8 9am country 2 10am 1500
    02/01/2017 FLI 101 country 9 3pm country 3 4pm 2000
    02/01/2017 FLI 101 country 10 2pm country 4 3pm 1000
    02/01/2017 FLI 101 country 11 4pm country 5 5pm 1000
    02/01/2017 FLI 101 country 12 9am country 6 10am 2000
    02/01/2017 FLI 102 country 1 12noon country 7 1pm 1000
    02/01/2017 FLI 102 country 2 10am country 8 11am 1000
    02/01/2017 FLI 102 country 3 1pm country 9 2pm 1500
    02/01/2017 FLI 102 country 4 4pm country 10 5pm 1000
    02/01/2017 FLI 102 country 5 9am country 11 10am 1500
    02/01/2017 FLI 102 country 6 3pm country 12 4pm 2000
    02/01/2017 FLI 102 country 1 12noon country 7 1pm 1000

    the actual data is above but for better understanding, the above is simplified to :

    Date flight from Start time to finish time distance(km)
    01/01/2017 FLI 101 country 1 2pm country 7 3pm 1000
    country 2 4pm country 8 5pm 1500
    country 3 9am country 9 10am 1000
    country 4 12noon country 10 1pm 1500
    country 5 10am country 11 11am 2000
    FLI 102 country 6 1pm country 12 2pm 1000
    country 7 4pm country 1 5pm 1000
    02/01/2017 FLI 101 country 8 9am country 2 10am 1500
    country 9 3pm country 3 4pm 2000
    country 10 2pm country 4 3pm 1000
    country 11 4pm country 5 5pm 1000
    country 12 9am country 6 10am 2000
    FLI 102 country 1 12noon country 7 1pm 1000
    country 2 10am country 8 11am 1000
    country 3 1pm country 9 2pm 1500
    country 4 4pm country 10 5pm 1000
    country 5 9am country 11 10am 1500
    country 6 3pm country 12 4pm 2000
    country 1 12noon country 7 1pm 1000

    • RodStephens says:

      If I understand (still not guaranteed), you might want some sort of tree/grid combination control. Unfortunately Visual Studio doesn’t have one.

      You could use a TreeView if you don’t need the data to be in a grid. I.e. if you’re okay having it in text as you shown above: country 6 3pm country 12 4pm 2000.

      Or I still think you could use master-detail in a DataGrid.

      One approach would be to lay out the interface you want using Word or something just so you can see exactly what you want. Then you can start looking for the controls you need to build it.

      In the very worst case, you could draw the data on something like a FlowDocument or FixedDocument. That would be a lot more work, but you get exactly what you want.

  20. yen says:

    Thank you very much for your help.
    Please how do I declare a 3 dimensional list of string to contain the data mentioned in my previous post?
    For example, the 3 dimensional list should be of the form [x, y, z]. Only x is known beforehand whilst the length for y and z can vary each time. This is has to be carried out for thousands of entries.
    Thank you.
    Yen.

    • RodStephens says:

      There are two basic approaches: arrays or lists.

      For arrays you need to initialize each of the entries separately. Here’s a small example.

      // 10 entries for x.
      int[][][] values = new int[10][][];
      
      // Entry [0] has 2 entries for y.
      values[0] = new int[2][];
      
      // Entry [0][0] has 5 entries for z.
      values[0][0] = new int[5];
      
      // Entry [0][1] has 2 entries for z.
      values[0][1] = new int[2];
      
      // Fill in values.
      values[0][0][0] = 1;
      values[0][0][1] = 2;
      ...
      

      Here’s an example that uses lists.

      List<List<List<int>>> values2 =
          new List<List<List<int>>>();
      
      // Add the first x value list.
      values2.Add(new List<List<int>>());
      
      // Add two lists for x = 0, y values.
      values2[0].Add(new List<int>());
      values2[0].Add(new List<int>());
      
      // Add some z values for x=0, y=0.
      values2[0][0].Add(1);   // values[0][0][0] = 1
      values2[0][0].Add(2);   // values[0][0][1] = 2
      values2[0][0].Add(3);   // values[0][0][2] = 3
      ...

      Sorry but both approaches are kind of confusing.

  21. yen says:

    Thank you very much for your help.
    Really appreciated.
    Good man.

  22. yen says:

    I was wondering, is it possible to add to enum without writing them individually if they are many entries

    public enum Test
    {
    Test1,
    Test4,
    ……..,
    ………,
    ……..,
    }
    up to 1,000 entries

    Many thanks

    • RodStephens says:

      The purpose of an enum is to make named values such as Chocolate, Vanilla, Strawberry. You can then use those values in your code so you have something easier to understand than numbers such as 0, 1, and 2.

      If you have 1,000 values, then probably their names aren’t as meaningful. For example, Test4 doesn’t mean a lot more than just 4. So you could just use an integer to represent the values instead of using an enum.

      You could also write code to verify that values are within an allowed range. For example:

      if ((value < 0) || (value > 1000))
          throw new Exception("Value " + value.ToString() +
              " is out of range");

      If you really want to make an enum with values like Test1, Test2, …, you could write a program to generate the statements as text and then copy and paste them into your program. Note that you can put multiple values the same line to save space.

      public enum Test
      {
      Test1, Test2, Test3, Test4, ...,
      Test11, Test12, Test13, Test14, ...,
      ...
      }

      If you *really* want to add values to an enum at run time, no you can’t do that. You could use some other data structure such as a list or dictionary to keep track of the allowed values.

  23. yen says:

    Thank you very much.

  24. yen says:

    Hi sir,
    Please how can I implement on window forms using a combo box or any other means to pick different values from a combo box and assign different values to what you have picked and then save all of the items you selected and assigned. E,g I might pick a fruit from the combo, and then assign it to a country where is it found and save. That there will be a list of fruits and list of countries.
    Many thanks

  25. RodStephens says:

    You’re going to have to decide how you want to store the data. A database would work well. A text file would also work but would be more application-specific.

    For a database, you’ll need tables holding the types of fruits and countries. You can probably store the country for each fruit in the Fruits table.

    When the program starts, read the tables and use them to initialize the combo boxes. When the user picks a Fruit, display its country in the other combo box. If the user changes the country, save the change.

    You can probably do this with bound controls. Search the internet for more information on that approach.

  26. yen says:

    Thank you very much.
    I think a text file would do.
    Please I will appreciate any sample code that can do this or any url link.
    Many thanks.

  27. yen says:

    you have not attached any file to download.
    I am referring to the combox example.

    • RodStephens says:

      I don’t have an example for that. You should try to follow the suggestions in the reply:

      Decide what kind of database you want to use. Build tables for the fruits and countries. When the program starts, load the combo boxes with the allowed values. When the user updates a choice or a fruit, save it into the database. (Or update the data table and then save the data later.)

  28. yen says:

    sir,

    Please how can i make sure that the value of calories change from one days to days

    for (int day = 0; i< 5; i++)
    {
        for (int i = 0; i<food.Count; i++)
        {
            food[i].calories = food[i].calories – xxx;
        }
    }

    I want to print out food for the five days to show the different calories for each day e.g
    Day 0, food.calories =x0
    Day 1, food.calories =x1
    Day 2, food.calories =x2
    Day 3, food.calories =x3
    Day 4, food.calories =x4

  29. yen says:

    Here is my code:

    private void button1_Click(object sender, EventArgs e)
    {
        int days = 3;
        int types = 3;
    
        Foood[] food = new Foood[types];
        food[0] = new Foood("protein", 2.0);
        food[1] = new Foood("vitamins", 3.0);
        food[2] = new Foood("Carbonhydrate", 4.0);
    
        List foods = new List();
    
        foods.Add(food[0]);
        foods.Add(food[1]);
        foods.Add(food[2]);
    
        for (int i = 0; i < days; i++)
        {
            UpdateCalories(foods);
        }
    
        using (StreamWriter sw = new StreamWriter(@"U:\Food\food.txt"))  //lboro
        {
            sw.WriteLine("Day" + "{0}", 0);
    
            for (int ii = 0; ii < types; ii++)
            {
                sw.WriteLine("{0},{1}", food[ii].Name, food[ii].calories);
            }
            sw.WriteLine("");
                    
    
            for (int i = 0; i < days; i++)
            {
                sw.WriteLine("Day" + "{0}", i + 1);
    
                for (int ii = 0; ii < types; ii++)
                {
                    sw.WriteLine("{0},{1}", food[ii].Name, food[ii].calories);
                }
                sw.WriteLine("");
            }
        }
    }
    
    public void UpdateCalories(List foodItem)
    {
        for (int i = 0; i < foodItem.Count; i++)
        {
            foodItem[i].calories = foodItem[i].calories + 1.1;
        }
    }
    
    public class Foood
    {
        public string Name { get; set; }
        public double calories { get; set; }
    
        public Foood(string name, double calory)
        {
            this.Name = name;
            this.calories = calory;
        }
    }

    I got this Output
    Day 0
    protein,5.3
    vitamins,6.3
    Carbonhydrate,7.3

    Day 1
    protein,5.3
    vitamins,6.3
    Carbonhydrate,7.3

    Day 2
    protein,5.3
    vitamins,6.3
    Carbonhydrate,7.3

    Day 3
    protein,5.3
    vitamins,6.3
    Carbonhydrate,7.3

    But I want this:

    Day 0
    protein,2.0
    vitamins,3.0
    Carbonhydrate,4.0

    Day 1
    protein,3.1
    vitamins,4.1
    Carbonhydrate,5.1

    Day 2
    protein,4.2
    vitamins,5.2
    Carbonhydrate,6.2

    Day 3
    protein,5.3
    vitamins,6.3
    Carbonhydrate,7.3

    • RodStephens says:

      First, you should use List<Foood> instead of just a plain List.

      The problem is that your loop that updates the amounts runs before the loop that displays the values. So by the time the second loop runs to save results into the file, the values have all been updated 3 times.

      Try moving the call to UpdateCalories inside the write loop like this:

      private void button1_Click(object sender, EventArgs e)
      {
          int days = 3;
          int types = 3;
      
          Foood[] food = new Foood[types];
          food[0] = new Foood("protein", 2.0);
          food[1] = new Foood("vitamins", 3.0);
          food[2] = new Foood("Carbonhydrate", 4.0);
      
          List foods = new List();
      
          foods.Add(food[0]);
          foods.Add(food[1]);
          foods.Add(food[2]);
      
          using (StreamWriter sw =
              new StreamWriter(@"U:\Food\food.txt"))  //lboro
          {
              for (int i = 0; i < days; i++)
              {
                  UpdateCalories(foods);
      
                  sw.WriteLine("Day" + "{0}", i + 1);
      
                  for (int ii = 0; ii < types; ii++)
                  {
                      sw.WriteLine("{0},{1}", food[ii].Name, food[ii].calories);
                  }
                  sw.WriteLine("");
              }
          }
      }
  30. yen says:

    Thank you very much.
    First, I tried your suggestion ….List foods = new List()but received error.
    Secondly, I actually want a situation where I can store the three days values before printing at all.
    Please assist further.
    I appreciate.

    • RodStephens says:

      You really should use List<Foood>. (The comments are removing the <Foood> part because the brackets < and > confuse the browser. You can use &lt; and &gt; to make it display correctly, although it’s more work.)

      You can’t do what you want the way you have it set up. The Foood class only has room for one value of each type so it can’t store 3 days worth of values.

      If you really want to do it that way, you need to change the class so it stores 3 days worth of data. For example, instead of making calories a double, you could make it double[] or a List<double>.

  31. yen says:

    Many thanks, I have already implemented what you suggested but the result is still the same

    • RodStephens says:

      If you made an array or list to hold data for each date, be sure you loop through the dates. For example:

      for (int i = 0; i < 3; i++)
          for (int day = 1; day < 3; day++)
              foodItem[i, day].calories = foodItem[i, day - 1].calories + 1.1;

      And be sure to loop through the different days when displaying the results.

  32. yen says:

    please kindly assist – the Designer View for form 1 in CSharp Visual Studio 2015 is missing. It only appears when i click the start button. Please how do i bring it back to edit the form.

    • RodStephens says:

      I’m not sure what the problem is. You should be able to click on the form in Solution Explorer and then click the View Designer button above to view the form designer.

      If it won’t open, you might have modified the form’s code behind in Form1.Designer.cs. In that case, you can try to fix the code, but it can be hard. Failing that, you may have to delete the form and build it again.

      Before you do that, you can copy and paste any code you have in Form1.cs into a text file so you can load it into the form later without so much typing.

  33. yen says:

    Hello sir,
    Please how do I send the output to an excel file?
    Cheers

  34. yen says:

    Thank you very much – really appreciate.
    I will explore them. Please what about converting existing .xlsx into .csv

    • RodStephens says:

      Excel can do that, too. If you can use Excel, load the .xlsx file and then use Save As to save in a CSV file.

      If you want to do it with a C# program, use code similar to the examples to open the .xlsx file. Then get the data that you want and write it into a text file in CSV format.

  35. yen says:

    Many thanks for your help.
    Please how can i filter and select from 3 different Lists in c# using multiple criteria.
    I need to select each from the 3 lists that satisfies the all the conditions. Please help again.
    thanks

    • RodStephens says:

      Without knowing exactly what you have in mind, I can think of two things to try. First look through the lists and perform the tests you need.

      Second, you might try LINQ. If you can figure out how to make LINQ do it (which can be hard), it will probably make your code simpler.

  36. yen says:
    
    public class Foood
    {
        public string Name { get; set; }
        public double calories { get; set; }
    
        public Foood(string name, double calory)
        {
            this.Name = name;
            this.calories = calory;
        }
    }

    I have two different List from the class above.
    How can I select from each list such that :
    x1.calories + x2.calories < CertainValue

    • RodStephens says:

      Ah. Try something like this:

      foreach (Foood food1 in list1)
      {
          foreach (Foood food2 in list2)
          {
              if (food1.calories + food2.calories < target)
                  Console.WriteLine(food1.Name + " and " + food2.Name);
          }
      }

      Instead of Console.WriteLine you could do something like add the foods to a pair of lists, a list of tuples, etc.

  37. yen says:

    Thank you very much for your help.

  38. yen says:

    Please how do create a class diagram from the Food project.
    thanks

  39. yen says:

    sorry, i mean if i want to automatically create UML diagrams for the entire project with class and many methods.
    thanks

  40. yen says:

    Thank you for your immense help.
    please if i have this:

    static void Main(string[] args)
    {
        List FoodList = new List()
        {
            new Food("Salad", 90),
            new Food("Steak", 202),
            new Food("Potato", 157),
            new Food("Cake", 235)
        };
    }

    please how do i put all the data inside the class rather than in the main method. The data is not going to change. The manipulations of the data will be in the main method. I just want to call an instance of the class and I expect the data to be included in each instance.
    Thanks

    • RodStephens says:

      It looks like you’re building a console application. In that case there is only one instance of the main method so you can’t really make multiple instance of it.

      You could make a class that holds the list and make multiple instances of that, but you still only have one instance of main to process them.

      If you make a Windows Forms application, then you can make multiple instances of the form multiple instances of a class that holds the list.

      One approach would be to make a Windows Forms application and then declare and initialize the list outside of any method but inside the form. Then any method inside the form can use the list. It would look something like this:

      public partial class Form1 : Form
      {
          public Form1()
          {
              InitializeComponent();
          }
      
          private List FoodList = new List()
              {
                  new Food("Salad", 90),
                  new Food("Steak", 202),
                  new Food("Potato", 157),
                  new Food("Cake", 235)
              };
      
          private void Form1_Load(object sender, EventArgs e)
          {
              // Do something with FoodList...
          }
      }
  41. yen says:

    Thank you for your prompt response.
    To be clear- it is not a console application at all. I think you have an idea of what i am doing.
    Actually there will be numerous data in the Food class. These will be loaded from many .CSV files.
    Manipulations will be performed on these data that will eventually change these data in the main program. I need to call many instances of these data in the main program to be able to make comparison of/with these changed data in the main program.
    I am currently loading everything from a button

    public void FoodButton_Click(object sender, EventArgs e)
    {
    ..loading all .CSVs etc
    
      all manipulations of .CSV data
    }

    This makes it difficult for me to call any instance of this. So i need to re- structure it so that all loading .csv will be in the food class etc and i will just need to call several instances of Food.
    i need to compare the results of the several instances also.

    Many thanks

    • RodStephens says:

      If you’re loading the data from a single CSV file, then I would load them all at once. It doesn’t need to be in a button, but it will be easier to just load them all and store them in a list or array.

      You could put that method in the Food class or not.

      You could give the Food class a constructor that takes as parameters the values from a row of the CSV file. Or the array of loaded CSV values and the index in the array for the object to initialize itself with.

      for (int i = 0; i < csv_array.GetBounds(0); i++)
          FoodList.Add(new Food(csv_array, i);
  42. yen says:

    Thank you very much for your assistance.

  43. yen says:

    Hello sir,
    Please I need to some assistance:
    I have a GUI with start button.
    On the GUI form I need to load data from CSV – (no issues here)
    Out of these loaded data, pick some and then assign parameters:
    Use check box to assign values (yes/no, click boxes ) on the loaded data from CSV file.
    e.g
    “vitamins”, available (yes/no)
    “Carbonhydrate”, available (yes/no)
    .
    .
    .I need to save these settings so that I will be able to use the saved setting when I click on the start button to execute some codes.
    Please how do I handle this?
    Many thanks
    Yen

    • RodStephens says:

      Make a CheckedListBox an put the CSV values in it. Then you can read the check marks to see what is selected.

      You can save the checked values in a file using your own CSV format. Or build a string holding the values and use File.WritueAllText to save it into a file.

  44. yen says:

    Thank you very much.
    Please is is Microsoft Visual Studio Ultimate 2013 with Update 4 free for all?

  45. yen says:

    Great many thanks

    Please how do i create a code wrapper?

    • RodStephens says:

      A wrapper is just a method that calls another method to make it easier to do something. For instance, in this example the LoadCsv method wraps up the process of reading a CSV file into an array.

      How your code wrapper works will depend on what you want to wrap.

  46. yen says:

    want to wrap the whole code to be opened from Java and pass input from inside Java to the code.

    • RodStephens says:

      Sorry but I don’t know how to call the code from Java.

      Probably what you need to do is create a library project and then use the library in Java. If you search the web for “call c# from java” you should find lots of posts that can help.

  47. yen says:

    thanks so much

  48. yen says:

    hello,
    I followed the link to download the Visual Studio Community version. After installation , it still telling me that it is for a trial period of time.
    Please am I missing anything?

    • RodStephens says:

      I think what it does is it give you a license that only lasts for a certain amount of time. When it expires, it renews itself so you shouldn’t ever really run out. Sometimes it can be annoying if you’re not connected to the internet because it seems to need to go to a server to renew.

      I’m not sure why they did it that way. Maybe it’s so they can stop everyone from running the old version when a new version comes out.

      But anyway, I wouldn’t worry about it unless it stops and can’t renew the license.

  49. yen says:

    well that makes sense.

  50. yen says:

    Hello Sir,
    Please kindly assist with how to go about progress bar. I could not figure out how to code the backgroundWorker1_DoWork.
    I saw some examples online but I need help.
    Many thanks

  51. yen says:

    Thanks for the effort so far. You have been helpful.
    From your experience, which one is better/faster between List and sql database?
    Cheers.

    • RodStephens says:

      It’s going to depend on a lot of things. If the SQL database isn’t on your computer, then you’ll have extra communication time. And different database engines may have different performance. If the list holds static information, then placing it on the users’ computers would reduce network traffic.

      In general, though, it shouldn’t matter too much unless you’re loading a ton of data. I’ve worked on projects with hundreds of users sharing a database (so obviously over a network) and performance was just fine.

      Probably you should assume both will work and then decide based on the features that you want.

  52. yen says:

    I really appreciate.
    You have been very helpful.
    Thanks for the effort so far.

    Cheers.

  53. Omar says:

    Hi,
    My data is big, 61000 record, using your code is slow when its trying to create the datagridview, is tehre other way? that tabulate the data then assign it to the gridview.

    • RodStephens says:

      Loading 61,000 records shouldn’t take too long but any control will have trouble displaying that much data. If you can tabulate or summarize the data to make it smaller first, you should have much better results.

  54. Omar says:

    Hi,

    I there is numbers like 10,222.00 the code dos not present the data right.

    • RodStephens says:

      Yes, the file uses commas to separate fields so if a value contains a comma, it won’t work.

      There are several ways you can handle this.

      • Use some other delimiter such as a tab instead of a comma.
      • Remove the commas from the numbers.
      • Enclose the values that contain commas with quotes. (Excel does that if you save a file into a CSV file.) Then you need to parse the file properly.
  55. yen says:

    Hello sir,
    Please how do i clone/deep copy/member copy etc of a list? which one is appropriate?
    What i really want to do is do many iterations :
    calories values will be changing from iterations to the next while i still want to retain some changing bool properties. I want to prevent a situation where bool properties will default back to false after cloning.

    • yen says:

      Please how do i do a shallow copy of a class with only some members?

      • RodStephens says:

        To copy the items in a list, loop through the list. If you want a shallow copy, add the existing item to the new list. If you want a deep copy, make a new instance of each item, copy the property values into the new item, and add the new item to the new list.

        Shallow copy:

        foreach (Person person in list1)
        {
            list2.Add(person);
        }

        Deep copy:

        foreach (Person person in list1)
        {
            Person new_person = new Person();
            new_person.FirstName = person.FirstName;
            new_person.LastName = person.LastName;
            ...
            list2.Add(new_person);
        }
  56. yen says:

    Maybe i should put it in another form: how can i implement a selective cloning of some member of a class and the leave some member properties.

    • RodStephens says:

      Suppose the Person class has properties MailingAddress and BillingAddress which are both Address objects. Then when you make a copy of a Person, you can make either of those deep or shallow copies of the original value.

      Shallow:

      new_person.MailingAddress = person.MailingAaddress

      Now the two Person objects share this address so changes to one also change the other.

      Deep:

      new_person.BillingAddress = New Address();
      new_person.BillingAddress.Street = person.BillingAddress.Street;
      new_person.BillingAddress.City = person.BillingAddress.City;
      ...

      Now the new Person has its own copy of the address so changes to one don't affect the other.

  57. yen says:

    Thank you so much

  58. yen says:

    But does your above explanation apply to a class?

  59. yen says:

    assuming you have up to 50 properties/members, can this be done automatically rather than listing them one by one in a foreach loop?

    foreach (Person person in list1)
    {
        Person new_person = new Person();
        new_person.FirstName = person.FirstName;
        new_person.LastName = person.LastName;
        ...
        list2.Add(new_person);
    }
  60. yen says:

    Thank you so much and have a nice day sir.

  61. yen says:

    Hello sir,
    Please kindly assist.
    I Could not write my .CSV output file. the error is :
    Access to the path ‘C:\Results.csv’ is denied.

    I have admin right on my machine.

    Please should i do?

    • RodStephens says:

      There are several reasons why you might not be able to write that file. For example, you may have admin privilege but I think access to the directory might be restricted. Your program could change that or it might be able to override that somehow, but it may be easier (and less messy) to put the file in a different directory such as C:\DataFiles.

  62. yen says:

    Many thanks

  63. yen says:

    Hi sir,
    Please kindly assist, how can I load data from different sheets inside a single excel file into a c# program.
    Cheers,
    Yen.

    • RodStephens says:

      See this post:

      Read Excel data in C#

      Look in the btnRead_Click event handler for the statement Excel.Worksheet sheet = (Excel.Worksheet)workbook.Sheets[1];. You can change the index in the Sheets collection to get other worksheets. Then use other code similar to that example to fetch the data you need.

  64. yen says:

    Awesome !!.You are an angel. Thank you very much. I will explore them.

    Secondly, Please how can successfully read floating point numbers from csv/Excel separated by either “.” or “,” or “;”.
    examples:
    100.99
    100,99
    100;99
    Many thanks

    Also, Please how can i run the .exe file from .net on Mac?

    • RodStephens says:

      If you use NumberStyles.Any as a second parameter to float.Parse, then it will handle things like currency symbols, thousands separators, and a decimal point in your locale, but it probably won’t handle ; or the wrong decimal separator. If you want to allow them, you’ll have to parse the text yourself. Regular expressions may be able to help.

      The Mac cannot run .NET executables natively. You can run them if you build them for Mono. Search the internet for “.NET Mono” and you should get lots of information.

      You may also be able to run UWP (Universal Windows Platform) apps on Mac OS, although I haven’t tried it. See these posts:

  65. yen says:

    Thanks to the guru. I will explore your solutions.

  66. yen says:

    Please help sir.
    I want to prematurely exit my program when it runs into errors.
    i used “Application.Exit()”; but did not work.
    I also tried “Environment.Exit(0)”; but i received the error below:
    “Error Creating Window Handle”

    Please kindly assist

    • RodStephens says:

      Sorry but I don’t know what’s wrong. Both of those methods work for me. I don’t think I’ve seen a program that couldn’t make Application.Exit work.

      Could it be that the errors you encountered were so severe that the application couldn’t even exit properly? For example, if you’re completely out of memory?

      It’s always better to end a program by closing all of the forms if you can. That gives it time to close files and otherwise clean up before it goes away.

  67. yen says:

    I’m so sorry for my late reply. Thank you very much. I will check my program.
    Only FindIndex, FindLast, FindLastIndex are available.
    Please how do I FindAllIndex of a list ?

  68. yen says:

    many thanks.
    cheers

  69. Hui says:

    Hi sir,
    I would like to know how to get the filename into an array and load the filename to CSV file. For example, this is the filename, File_1_20170428101607. I want the file name (date and time format – 28/04/2017 10:16:07) to be parse into a column in the output file.

    • Hui says:
      private static string[] GetFileNames(string path, string filter)        {
          string fileName = @"C:\\Desktop\\File_1_20170428101607.csv";
      
          string result;
      
          result = Path.GetFileName(fileName);
          Console.WriteLine("GetFileName('{0}') returns '{1}'",
              fileName, result);
      
          string[] files = Directory.GetFiles(path, filter);
          for (int i = 0; i < files.Length; i++)
          {
              if (parsing was not possible) return null;
              ...
          }
      }
      • RodStephens says:

        I’m not completely sure what you want. Do you mean you want to find files with names like that one and then add the date and time pieces to a CSV file?

        You could use the string class’s SubStr method to pull out the pieces since it seems like they always have the same positions.

        foreach (string filename in files)
        {
            int len = filename.Length;
            int second_start = len - 2;
            int minute_start = len - 4;
            int hour_start = len - 6;
            int day_start = len - 8;
            int month_start = len - 10;
            int year_start = len - 14;
        
            string second = filename.Substring(second_start, 2);
            string minute = filename.Substring(minute_start, 2);
            string hour = filename.Substring(hour_start, 2);
            string day = filename.Substring(day_start, 2);
            string month = filename.Substring(month_start, 2);
            string year = filename.Substring(year_start, 4);
            string result = string.Format(
                "{0:2}/{1:2}/{2:4} {3:2}:{4:2}:{5:2}",
                day, month, year, hour, minute, second);
        
            // Add result to the CSV file ...
        }

        If you want to get fancy, you could use regular expressions.

  70. Thanks for posting such an excellent solution.

    I cant figure out where “filename” comes from. Its not declared and I looked everywhere in your code. is it just part of the method?

    Bwelow is the specific line of code that has me mystified. You declare the path here:

    private void Form1_Load(object sender, EventArgs e)
    {
        txtFile.Text = Path.GetFullPath(
            Path.Combine(Application.StartupPath, "..\\..")) +
                "\\Data.csv";
            txtFile.Select(0, 0);
    }

    Then after the btngo form, you use the string variable filename here. It never shows up as a declared string and I cant figure it out:

    // Load a CSV file into an array of rows and columns.
    // Assume there may be blank lines but every line has
    // the same number of fields.
    private string[,] LoadCsv(string filename)
    {
        // Get the file's text.

    Cheers,
    Karl

    • RodStephens says:

      The following statement declares filename as a parameter to the LoadCsv method.

      private string[,] LoadCsv(string filename)

      Then the following statement calls that method passing in txtFile.Text as the parameter.

      string[,] values = LoadCsv(txtFile.Text);

      The value of txtFile.Text is passed in so its value is assigned to filename while the method is running.

      • Thanks for replying. As you pointed out, the problem I had was not understanding that the loadcsv method is deployed in the same way a function definition is. Such a noob.

        • RodStephens says:

          Lol. Even non-noobs miss things occasionally, particularly since you didn’t write the code. What makes sense for one developer doesn’t always make sense for everyone else. (A pretty big problem with software development.)

  71. SaiNave says:

    Hi I need help,
    I want to store the text file data in an array like:
    1.Reads the text file consisting of 2 columns. Text file data of each column should be stored in 2 different arrays
    2. The Arrays are of fixed dimension as they only store 10 values
    3. Arrays behave like FIFO(first in first out), as once all the 10 values filled then It updates it self one by one again to store new values up to 10

  72. yem says:

    Hello Sir,
    Long time.
    I am trying to load CSV file into C# code but there few empty fields in the csv file.
    Please how can I make it to put such empty field as null inside the c# code.
    Many thanks.

    • RodStephens says:

      This example should work if there are missing fields. Then should show up in the CSV file as two commas with nothing between them as in:

      Field1,Field2,,Field4

      If there is no spot where there are two commas next to each other, then the row doesn’t have the right number of fields. In that case there’s no simple way to know which field is missing. You would need to know about the specific application. For example, can you tell because a numeric field is missing?

      If there’s no way to tell the fields apart, for example they are all name fields, then you can’t do this.

  73. yen says:

    There are commas as you said but an error is flagged as i am trying to copy from the initial string into a list.

    • RodStephens says:

      I don’t know why the example wouldn’t work. The Split method can handle adjacent commas and would leave a blank item in the array that it returns. (The example program worked on a quick test.)

      You should make sure that every line has the right number of commas. Different lines have different numbers of fields, the program might get confused, depending on how you wrote it.

  74. yen says:

    Okay thanks.
    One more thing.
    How do i covert a .cs file into a .dll and put in reference so that i can delete the .cs file from the solution.
    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *