Next Door Engineer
Next Door Engineer

Reputation: 2886

Reading each row from text file into an array of doubles or integer using C#

Suppose I have a text file with data like below, I want to read first row and store the elements in one array. Read the second row and store in second array and so on. I will be making some manipulations on the array later on. Can you help me to do this in C#?

Input text file:

5,7,3,6,9,8,3,5,7

5,6,8,3,4,5

6,4,3,2,65,8,6,3,3,5,7,4

4,5,6,78,9,4,2,5,6

The Code I am trying out is:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace ReadFile
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        static void Main(string[] args)
        {
            TextReader tr = new StreamReader("Data.txt");
            // write a line of text to the file
            string word = tr.ReadLine();
            //now split this line into words
            string[] val = word.Split(new Char[] { ',' });
        }
    }

}

If I use the above technique, I can get the first line in array val. Is there a way to loop it for all the rows?

Upvotes: 1

Views: 3700

Answers (7)

Next Door Engineer
Next Door Engineer

Reputation: 2886

I figured it out. Thanks all for your time!

private void ReadFile()
    {
        var lines = File.ReadLines("Data.csv");
        var numbers = new List<List<double>>();
        var separators = new[] { ',', ' ' };
        /*System.Threading.Tasks.*/
        Parallel.ForEach(lines, line =>
        {
            var list = new List<double>();
            foreach (var s in line.Split(separators, StringSplitOptions.RemoveEmptyEntries))
            {
                double i;

                if (double.TryParse(s, out i))
                {
                    list.Add(i);
                }
            }

            lock (numbers)
            {
                numbers.Add(list);
            }
        });

Upvotes: 0

Ozair Kafray
Ozair Kafray

Reputation: 13539

I have presented the following code in two sections, just to show you in steps.

SECTION 1

This code is just to show that you just needed to loop through all lines and store string numbers from each line in a List.

SECTION 1

static void Main(string[] args)
{
     List<string[]> allLines = new List<string[]>();

     TextReader tr = new StreamReader("Data.txt");
     string word = tr.ReadLine();

     // write a line of text to the file
     while ( word !=  null ) {

         //now split this line into words
         string[] vals = word.Split(new Char[] { ',' });

         //Add this line into allLines
         allLines.Add(vals);

         //Now read the next line
         word = tr.ReadLine();
     }
}

SECTION 2

This section will get you the results as int.

static void Main(string[] args)
{
     //A list of arrays of integers
     //A single array will have numbers from a single line
     List<int[]> allNumbers = new List<int[]>();

     TextReader tr = new StreamReader("Data.txt");
     string word = tr.ReadLine();

     // write a line of text to the file
     while ( word !=  null ) {

         //now split this line into words
         string[] vals = word.Split(new Char[] { ',' });
         int[] intVals = new int[vals.Length];

         for ( int i = 0; i < vals.Length; i++) {
             Int32.TryParse(vals[i], out intVals[i]);
         }

         //Add this array of integers into allNumbers
         allNumbers.Add(intVals);

         //Now read the next line
         word = tr.ReadLine();
     }
}

NOTE: I have not compiled or tested the code above.

Upvotes: 0

Ria
Ria

Reputation: 10347

See this lines of code:

List<List<int>> numbers = new List<List<int>>();
foreach (string line in File.ReadAllLines(""))
{
    var list = new List<int>();
    foreach (string s in line.Split(new[]{',', ' '}, 
                                    StringSplitOptions.RemoveEmptyEntries))
    {
        int i;
        if(int.TryParse(s, out i))
        {
            list.Add(i);
        }
    }
    numbers.Add(list);
}

var specialNumber = numbers[3][4];        // gives line 3 number 4
var specialLine = numbers[2].ToArray();   //  gives an array of numbers of line 2

description: I used this useful Generic:

  • List: Represents a strongly typed list of objects that can be accessed by index

and these useful Classes:

  • File.ReadAllLines: Opens a text file, reads all lines of the file into a string array
  • String.Split : Returns a string array that contains the substrings in this instance that are delimited by elements of a specified string or Unicode character array.
  • Int.TryParse: Converts the string representation of a number to its 32-bit signed integer equivalent.

Upvotes: 0

Phil
Phil

Reputation: 2365

Try this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.IO;
using System.Xml.Linq;
using System.Diagnostics;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {

            List<int[]> arrays = new List<int[]>();

            int counter = 0;
            string line;

            // Read the file
            System.IO.StreamReader file =
               new System.IO.StreamReader("c:\\temp\\test.txt");
            while ((line = file.ReadLine()) != null)
            {
                // split the line into a string array on , separator
                string[] splitLine = line.ToString().Split(',');

                // if our split isnt null and has a positive length
                if (splitLine != null && splitLine.Length > 0)
                {

                    // create a lineArray the same size as our new string[]
                    int[] lineArray = new int[splitLine.Length];

                    int posCounter = 0;

                    foreach (string splitValue in splitLine)
                    {
                        // loop through each value in the split, try and convert
                        // it into an int and push it into the array
                        try
                        {
                            lineArray[posCounter] = Int32.Parse(splitValue);
                        }
                        catch { }
                        posCounter++;
                    }

                    // if our lineArray has a positive length then at it to our
                    // list of arrays for processing later.
                    if (lineArray.Length > 0)
                    {
                        arrays.Add(lineArray);
                    }
                }
                counter++;
            }

            file.Close();

            // go through the List<int[]> and print to screen
            foreach (int[] row in arrays)
            {
                foreach (int rowCol in row)
                {
                    Console.Write(rowCol + ",");
                }
                Console.WriteLine();
            }

            // Suspend the screen.
            Console.ReadLine();
        }
    }
}

Upvotes: 0

Felice Pollano
Felice Pollano

Reputation: 33252

Ok, since you are a beginner my suggestions on what to focalize your attention. First of all, are your consumer always needing all the lines or can it stop at some point? If so, use a yield strategy to return the results one by one. You can use a StreamReader to read line one by one in any case, and use double.TryParse(...) or int.TryParse() after splitting the string by the separator. Keep an eye to the fact that separator can change, so use it with some kind of configurability, and in the case of double, ensure your code works even in machines with a different decimal point configured. If you are sure your csv alwais uses '.' as a decimal point separator, specify

double.TryParse("",System.Globalization.CultureInfo.InvariantCulture);

Upvotes: 1

Ebad Masood
Ebad Masood

Reputation: 2379

Something roughly like this would work:

StreamReader reader = new (File.OpenRead(@"YourFile.txt"));
List<string> LstIntegers = new List<string>();

            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();
                //values is actually a string array.
                var values = line.Split(',');
                //add the entire array fetched into string List
        LstIntegers.AddRange(values);   
            }
          // important to close the reader. You can also use using statement for reader. It 
          // will close the reader automatically when reading finishes.
            reader.Close();

   // You can then further manipulate it like below, you can also use int.Parse or int.TryParse:
   foreach (var v in LstIntegers)
   {
      // use int.TryParse if there is a chance that a non-int is read.
      int someNum = Convert.ToInt32(v);

   }

Upvotes: 0

Giedrius
Giedrius

Reputation: 8540

File.ReadAllLines will help you read all lines from file as string array.
String.Split will help you split line in pieces.
Int.Parse will help you transform string to int (double has similar method).

Upvotes: 3

Related Questions