0

Trying to read a .txt file that contains problem data varying in size and type (i.e. single integer, double/integer/binary arrays) for a computational experiment. By reviewing examples available here and here, I developed two alternative code blocks, but for some reason (I guess the Trim method does not work) they don't work. It gives the error of 'Input string was not in a correct format.' Does anyone let me know what I did wrong or what I missed?

using System;
using System.IO;
namespace Program
{
   class Program
{
    // Basic parameters
    private static int x, y, z;
    private static double[,] array= new double[x, x];

    static void Main(string[] args)
    {
        string fileName = "LUU1_5.txt";
        ReadFile(fileName);            
    }

    static void ReadFile(string sourcefile) 
    {
        using (TextReader reader = File.OpenText(sourcefile)) 
        {
            // Method-1 Read line by line
            //x= int.Parse(reader.ReadLine());
            //y= int.Parse(reader.ReadLine());
            //z= int.Parse(reader.ReadLine());
            //int k=0;

            //for (int row2 = 3; row2 < 3 + 1 + x; row2++)
            //{
            //    k = 0;
            //    foreach (var row2 in reader.ReadLine()) 
            //    {
            //        foreach (var col in row2)
            //        {
            //            Console.WriteLine(col.Trim());
            //            //array[row2 - 3, k] = double.Parse(col.Trim());                //            
            //            k++;
            //        }
            //    }                       
            //}

            // Method 2-Read All Lines
            String[] content = File.ReadAllLines(sourcefile);                

            x= int.Parse(content[0]);
            y= int.Parse(content[1]);
            z= int.Parse(content[2]);

            int j = 0;
            for (int row = 3; row < 3 + 1 + x; row++)
            {
                j = 0;
                foreach (var col in content[row].Trim().Split(" "))
                {
                    Console.WriteLine(content[row]);
                    Console.WriteLine(col);
                    Console.WriteLine(col.Trim());   // using console for monitoring the output
                    Console.WriteLine(content[row].Trim().Split(" "));
                    array[row - 3, j] = double.Parse(col.Trim());
                    //array[row-3, j] = double.TryParse(col.Trim(), out array[row-3, j]);
                    j++;
                }
            } 
            // Then the program reads the next 0-1 array starting line 10.                               
            reader.Close();                 
        }
    }
 }
 }

The data file looks like this:

5
2
100000
0   46.1    33.53   48.37   44.82   47.8
46.1    0   15.65   21.38   42.05   85.48
33.53   15.65   0   17.2    45.18   77.62
48.37   21.38   17.2    0   60.64   94.26
44.82   42.05   45.18   60.64   0   57.08
47.8    85.48   77.62   94.26   57.08   0
0   1   0   0   0   0
0   0   1   1   1   1
0   0   0   1   1   1
0   0   0   0   1   1
0   0   0   0   0   1
0   0   0   0   0   0

Also, I will be reading larger data files such as 500x500 or 1000x1000 for array-x later in this experiment, do you think I have any speed or memory issues? Which method should I use (line by line or all lines in one)? I'd like to design the read block accordingly now.

Thanks in advance!

Yusuf
  • 41
  • 7
  • Yo u have more than on space between columns and may have tabs. Try following : content[row].Trim()..Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); – jdweng Dec 01 '20 at 18:36
  • @jdweng, Thank you for pointing the difference between space and tab in the data file. Did not notice this. Your suggestion worked, I also replaced tabs with spaces as an alternative. – Yusuf Dec 01 '20 at 21:43

1 Answers1

0

I think it's better to use DTO and regex.

public sealed class RowData
{
    public RowData(int number, int size = 5)
    {
        Number = number;
        Items = new List<float>(size);
    }

    public int Number { get; private set; }
    public List<float> Items { get; set; }

    public override string ToString()
    {
        return $"{Number}:{string.Join(" ",Items)}";
    }
}

static void ReadFile(string fileName)
{
    var regex = new Regex("[\\d\\.]+");
    var list = new List<RowData>();
    using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        using (var sr = new StreamReader(stream, Encoding.UTF8))
        {
            string line;
            var number = 0;
            int x =0;
            int y = 0;
            int z = 0; 
            while ((line = sr.ReadLine()) != null)
            {
                switch (number)
                {
                    case 0:
                        x = int.Parse(line);
                        break;
                    case 1:
                        y = int.Parse(line);
                        break;
                    case 2:
                        z = int.Parse(line);
                        break;
                    default:
                        var rowData = new RowData(number - 3);
                        var matches = regex.Matches(line);
                        foreach (Match match in matches)
                        {
                            var value = match.Value;
                            if (CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator != ".")
                                value = value.Replace(".", CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
                            rowData.Items.Add(float.Parse(value));
                        }

                        list.Add(rowData);
                                break;

                }

                number++;

                
            }
        }
    }
    foreach (var rowData in list)
    {
        Console.WriteLine(rowData.ToString());
    }
}
Stanislav
  • 390
  • 2
  • 6