0

I have a C# console application where an external text file is read. Each line of the file has values separated by spaces, such as:

1 -88 30.1
2 -89 30.1

So line one should be split into '1', '-88', and '30.1'.

What I need to do is to populate an array (or any other better object) so that it duplicate each line; the array should have 3 elements per row. I must be having a brain-lock to not figure it out today. Here's my code:

string line;
int[] intArray;
intArray = new int[3];
int i = 0;

//Read Input file
using (StreamReader file = new StreamReader("Score_4.dat"))            
{   
    while ((line = file.ReadLine()) != null && line.Length > 10)
    {                    
        line.Trim();
        string[] parts;
        parts = line.Split(' ');
        intArray[0][i] = parts[0];//error: cannot apply indexing
        i++; 
    }
}

Down the road in my code, I intend to make some API calls to a server by constructing a Json object while looping through the array (or alternate object).

Any idea? Thanks

7
  • 4
    int[] has only one dimension Commented Oct 23, 2018 at 19:33
  • 1 -88 30.1 looks to be 10 characters, so line.Length is probably not > 10. You should get comfortable with your debugger and looking to see what is happening. Commented Oct 23, 2018 at 19:33
  • Thanks. I dont know what to do. This should be easy--but not today. Commented Oct 23, 2018 at 19:34
  • The actual values in my sample are very truncted--to keep the code clean. Each line has at least 15 characters. Commented Oct 23, 2018 at 19:35
  • 1
    line.Trim() effectively does nothing - Trim is a function so it returns the trimmed string, not trims the string. Commented Oct 23, 2018 at 19:36

5 Answers 5

2

If you only need the data to be transferred to JSON then you don't need to process the values of the data, just reformat it to JSON arrays.

As you don't know the number of lines in the input file, it is easier to use a List<>, whose capacity expands automatically, to hold the data rather than an array, whose size you would need to know in advance.

I took your sample data and repeated it a few times into a text file and used this program:

static void Main(string[] args)
{
    string src = @"C:\temp\Score_4.dat";
    List<string> dataFromFile = new List<string>();
    using (var sr = new StreamReader(src))
    {
        while (!sr.EndOfStream)
        {
            string thisLine = sr.ReadLine();
            string[] parts = thisLine.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length == 3)
            {
                string jsonArray = "[" + string.Join(",", parts) + "]";
                dataFromFile.Add(jsonArray);
            }
            else
            {
                /* the line did not have three entries */
                /* Maybe keep a count of the lines processed to give an error message to the user */
            }
        }
    }

    /* Do something with the data... */
    int totalEntries = dataFromFile.Count();
    int maxBatchSize = 50;
    int nBatches = (int)Math.Ceiling((double)totalEntries / maxBatchSize);
    for(int i=0;i<nBatches;i+=1)
    {
        string thisBatchJsonArray = "{\"myData\":[" + string.Join(",", dataFromFile.Skip(i * maxBatchSize).Take(maxBatchSize)) + "]}";
        Console.WriteLine(thisBatchJsonArray);
    }

    Console.ReadLine();
}

to get this output:

{"myData":[[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1]]}
{"myData":[[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1],[1,-88,30.1],[2,-89,30.1]]}

It should be easy to adjust the format as required.

Sign up to request clarification or add additional context in comments.

7 Comments

Hi, the JSON hard-coded code that I tried and worked was formated like this: string json = @"[{'Methodology': '2', 'ID': '1', 'latitude': '30.7000', 'longitude': '-88.000 }, { 'methodology': '2', 'id': '2', 'latitude': '30.60002', 'longitude': '-88.0000'}]";
Never mind; I think I am figuring out the format per the hard-coded one I just commented above. Thanks.
@IrfanClemson Yes, it can be a bit fiddly getting all the parts together: it might even be worth making a small separate function to take an array of strings and return the JSON version that you need.
Hi, almost there. parts[2] = "'latitude':" + "'" + parts[2] + "'"; parts[3] = "'Methodology':" + "'2'";
So I need to add a hard-coded fourth element: parts[3] but am getting an index out of range error.
|
2

I would create a custom Item class and then populate a list, for easy access and sorting, with self contained items. something like:

 public Class MyItem
 {
     public int first { get; set; }
     public int second { get; set; }
     public float third { get; set; }

     public MyItem(int one, int two, float three)
     {
         this.first = one;
         this.second = two;
         this.third = three;
     }
}

then you could do:

List<MyItem> mylist = new List<MyItem>();

and then in your loop:

using (StreamReader file = new StreamReader("Score_4.dat"))            
{   
    while ((line = file.ReadLine()) != null && line.Length > 10)
    {                    
        line.Trim();
        string[] parts;
        parts = line.Split(' ');
        MyItem item = new Item(Int32.Parse(parts[0]),Int32.Parse(parts[1]),Float.Parse(parts[2]));
        mylist.Add(item);
        i++; 
    }
}

5 Comments

MyItem item = new Item(Int32.Parse(parts[0]), Int32.Parse(parts[1]), Float.Parse(parts[2]));
Type of namespace Item could not be found. Also, Float doesn't exist in current context; note, all these can be String values! No need for float or int etc. Thanks.
Accepted PrinceOfRavens answer. Some typo in the Answer but I figured out. Thanks!!
@IrfanClemson looks like you accepted Andrew Morton's answer. but no worries, i gave him plus one too!
Hi, I had accepted your's and I think it would have worked after me creating the JSON object. His answer also takes care of the JSON object creation. I wish I could accept both or give your more thumbs up! Thank you!
0

As there are numbers like 30.1 so int is not suitable for this, and also it must not be a double[] but double[][]:

string[] lines = File.ReadAllLines("file.txt");
double[][] array = lines.Select(x => s.Split(' ').Select(a => double.Parse(a)).ToArray()).ToArray();

Comments

0

Issue is that int array is single dimensional.

My suggestion is that you can put a class with 3 properties and populate a list of class there. It's better to have class with same property names that you require to build JSON. So that you can easily serialize this class to JSON using some nugets like Newtonsoft and make api calls easily.

Comments

0

Your int array is a single dimensional array yet you're trying to index it like a multidemensional array. It should be something like this:

intArray[i] = parts[0]

(However you'll need to handle converting to int for parts that are fractional)

Alternatively, if you want to use a multidimensional array, you have to declare one.

int[][] intArray = new int[*whatever your expected number of records are*][3]

Arrays have a static size. Since you're reading from a file and may not know how many records there are until your file finishes reading, I recommend using something like a List of Tuples or a Dictionary depending on your needs.

A dictionary will allow you to have quick lookup of your records without iterating over them by using a key value pair, so if you wanted your records to match up with their line numbers, you could do something like this:

Dictionary<int, int[]> test = new Dictionary<int, int[]>();
int lineCount = 1;
while ((line = file.ReadLine()) != null && line.Length > 10)
   {
      int[] intArray = new int[3];
      line.Trim();
      string[] parts = line.Split(' ');
      for (int i = 0; i < 3; i++)
          {
               intArray[i] = int.Parse(parts[i]);
          }
      test[lineCount] = intArray;
      lineCount++;

  }

This will let you access your values by line count like so:

test[3] = *third line of file*

2 Comments

Thanks. Will this lead to each row of the array with elements like they are on each line? So element 1 on row 1 will have 1, and element 1 on row 2 will have 2? It would help if you write your Answer in a bit more detail?
Not quite. Arrays are indexed at 0 in C#, so element 1 will be 0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.