How to read numbers from a txt file in C#?

Asked

Viewed 726 times

1

This is an example file:

2
0.03159527 0.1990048 0.9794891
0.02173799 0.9969404 0.07508247

The first number indicates how many lines are, for each line are always three numbers

I tried to do something like this:

    Vector3[] Load()
{
    StreamReader entrada = new StreamReader ("gestos_saida.txt");

    int size = entrada.Read ();
    Vector3[] v = new Vector3[size];
    for (int i = 0; i < size; i++)
    {
        float x, y, z;
        x = entrada.Read ();
        y = entrada.Read ();
        z = entrada.Read ();
        v[i] = new Vector3 (x, y, z);
    }

    entrada.Close ();
    return v;
}

But the numbers read do not match the file, as I can read these numbers without using a ReadLine() and then break the string?

  • 1

    I don’t understand. What do you intend to do?

  • 1

    Put in more parts of the code, what is this entrada?

  • 2

    You could use a readline and then split by space.

  • I edited and entered the complete code

2 answers

3


You can’t, you have to be manual. You have to read the lines, break the data and convert it. I considered that the file will always be well formatted and with correct data. Something like this:

using System;
using static System.Console;
using System.IO;

public class Program {
    public static void Main(string[] args) {
        var texto = "2\n0.03159527 0.1990048 0.9794891\n0.02173799 0.9969404 0.07508247";
        using (var reader = new StringReader(texto)) { //só trocar para o arquivo aqui
            int size = int.Parse(reader.ReadLine());
            for (int i = 0; i < size; i++) {
                string[] linha = reader.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                WriteLine($"{linha[0]}, {linha[1]}, {linha[2]}"); //depois troca para o Vector3
            }
        }
    }
}

Behold working ideone. And in the .NET Fiddle. Also put on the Github for future reference.

  • solved my problem, I just found that it is solved in a very prolific way, in c++ for example we can use Cin without any concern with treatment of types, which makes the code much leaner, I imagined that in c# it was similar

  • @Andrécarvalho is true that C# is not so good at conversions. Of course, nothing prevents you from creating a library that abstracts this in a similar way to C++. Of course it’s work and I don’t think anyone did it, which gives me an idea, maybe I’ll make one someday :) It’s obvious that language doesn’t help some things, everyone who wants to make their type conform to this library will have to implement an extension method since there is no operator of stream in the C#.

2

I understand your logic. You want to store text value information for three-element vectors. I just don’t understand if you want to do this to generate a single vector or want to store multiple vectors, but surely both cases are possible. You just need to define a logic for your text. If you store an immutable fixed number of vectors of three numbers, you can store everything in a 3x matrixn, where n is the number of column vectors to be stored (in this case as specified as the first number in the text file). I call it "matrix" for its concept of linear algebra, but it is nothing more than a array vector, so it will be a vector type[n], as apparently is what you want.

Let’s assume that you want to store everything in an array. In this implementation, what we would do is:

  1. Read the first line to define the dimensions of a matrix (array of vectors);
  2. Read each row of three numbers divided by spaces;
  3. Divide each string between its spaces;
  4. Fill in the template with strings obtained by converting them to float or double (depending on the accuracy you want).

Below is the detailed implementation:

using System;
using System.Linq;

namespace Programa
{
      public class Program
      {
            Vector3[] Load(string filePath)  // Endereço do arquivo
            {
                Vector3[] v;
                using (StreamReader sr = new StreamReader(filePath))
                {
                    string[] linha;
                    float[] nrs = new float[3];
                    int size = int.Parse(sr.ReadLine());  // Leio a primeira linha apenas, com o número de vetores da matriz
                    int i = 0;
                    v = new Vector3[size];

                    while (!sr.EndOfStream && i < size)
                    {
                        linha = sr.ReadLine().Split(' ');  // Divido pelos espaços
                                                           // Veja as outras sobrecargas de Split para mais opções
                        nrs = linha.Select(n => float.Parse(n)).ToArray();  // Uso Linq para selecionar cada elemento e converter para float
                        v[i] = new Vector3 (nrs[0], nrs[1], nrs[2]);
                        i++;
                    }
                }
                return v;
            }
      }
}

Instead of float. Parse, use double.Parse for double decimal precision if desired. Also, always recommend (!!) using the blocks using as I used now, as they ensure that the Streamreader will be arranged after use.

(Note: I haven’t tested the algorithm yet, I’m on Linux at the moment. Of course, I edit later if there are any problems)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.