Sabotenderizer
Sabotenderizer

Reputation: 187

Splitting data from a text file into parallel arrays

My professor gave the class an example of C# that can be used to split data from a text file. I am trying to use it for a project that involves splitting the contents of a txt. file into 4 arrays or fields. Here is the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

class Program
{
    static void Main()
    {
        int i = 0;
        foreach (string line in File.ReadAllLines("census.txt"))
        {
            string[] parts = line.Split(',');
            foreach (string part in parts)
            {
                Console.WriteLine("{0}",

                    part);
            }
            i++; 
        }
    }
}

Here is census.txt:

21,f, s, 14

41,f, m, 22

12, m, s, 12

11, f, s, 8

29, m, m, 4

6, m, s, 12

9, f, s, 2

30, f, s, 1

It's supposed to be hypothetical census data going by age, gender, marital status, and district. The output I keep getting is each of those numbers or chars in a single line like so:

21

f

s

14

41

f

m

22

and so on.

I think it means it's working but I'd like to know how to use this for entering into 4 parallel arrays. I would also to know more about splitting it into 4 fields, structs, or classes. The next part of the project involves counting every time a certain age number or district number appears and that will involve a lot of arrays.

Upvotes: 0

Views: 4887

Answers (4)

user11472119
user11472119

Reputation: 11

This is old thread, but as google shows it among first few pages I decided to send my comment. I strongly advise against given txt file format, because it is not error proof. If census.txt is not guaranteed to be ideal and especially if it is supposed to be created by some third party (user, administrator, whoever) then I strongly recommend records to be ended with some symbol, like this: 21,f, s, 14;

41,f, m, 22; then first thing what we do - we get array of records, like this:

string[] lines = text.split(';');

then simply split again - this time to get record elements.

foreach (string record in lines)

{

string[] fields = record.split(',');

}

This way it is not only easier to read records/fields, but also you can easily check consistency of file, ignore errors (empty records), check number of fields in each records and etc.

Upvotes: 1

Tim
Tim

Reputation: 28530

A generic list (as used in the other 2 current answers here) is the best way to go. However, if you need to have the data in arrays (as your previous question seems to indicate), then you can modify your professor's code like this:

C#

int[] districtDataD = new int[900];
string[] districtDataG = new string[900];
string[] districtDataM = new string[900];
int[] districtDataA = new int[900];

int i = 0;
foreach (string line in File.ReadAllLines("census.txt"))
{
    string[] parts = line.Split(',');

    districtDataD[i] = int.Parse(parts[0]);
    districtDataS[i] = parts[1];
    districtDataM[i] = parts[2];
    districtDataA[i] = int.Parse(parts[3]);
    i++;
}

VB.NET (Since your original question was tagged with VB.NET):

Dim districtDataD() As New Integer(900)
Dim districtDataS() As New String(900)
Dim distrcitDataM() As New String(900)
Dim districtDataA() As New Integer(900)

Dim i As Integer = 0

For Each Dim line As String In File.ReadAllLines("census.txt")
    Dim string() As parts = line.Split(',')

    districtDataD(i) = Integer.Parse(parts(0))
    districtDataS(i) = parts(1)
    districtDataM(i) = parts(2)
    districtDataA(i) = Integer.Parse(parts(3))

    i++
Next

You could also use a struct or class and have one array that holds that object, but it looks like you're professor wants you to use 4 separate arrays. If you can use one, you can simply declare the array like this, for example:

C#

Person[] districtData = new Person[900];

VB.NET

Dim districtData() As New Person(900)

Then you could do this inside the split logic (note that if, say Distric and Age are integers in your object you'll have to cast or parse them as I show below):

C#

districtData[i] = new Person() { District = int.Parse(parts[0]), Gender = parts[1], MaritalStatus = parts[2], Age = int.Parse(parts[3]) };

VB.NET

districtData[i] = new Person() With { .District = Integer.Parse(parts[0]), .Gender = parts[1], .MaritalStatus = parts[2], .Age = Integer.Parse(parts[3]) }

There's a risk with this code that if you have more than 900 lines of data, you will get an index out of range exception. One way to avoid this would be to modify the code I put above with a while loop that checks the bounds of the target array(s) or the the number of lines haven't been exceed, like this:

C#

string[] lines = File.ReadAllLines("census.txt");
int i = 0;

while (i < 900 && i < parts.Length)
{

    // split logic goes here
}

VB.NET

Dim lines As String() = File.ReadAllLines("census.txt")
Dim i As Integer = 0

While (i < 900 AndAlso i < lines.Length)

    ' split logic goes here
End While

I haven't tested the code, but this will hopefully help you if you must use arrays.

Upvotes: 0

MarcinJuraszek
MarcinJuraszek

Reputation: 125630

I would extend irsog's answer a bit:

  • Use a class instead of a structure
  • Use properties instead of fields
  • Use Gender and MaritalStatus enums instead of plain strings

Code:

public class Person
{
    public int Age { get; set; }
    public MaritalStatus MaritalStatus { get; set; }
    public Gender Gender { get; set; }
    public int District { get; set; }
}

public enum MaritalStatus
{
    Single, Married
}

public enum Gender
{
    Male, Female
}

And usage:

var people = new List<Person>();

foreach (string line in File.ReadAllLines("Input.txt"))
{
    string[] parts = line.Split(',');

    people.Add(new Person()  {
        Age = int.Parse(parts[0]),
        MaritalStatus = parts[1] == "s" ? MaritalStatus.Single : MaritalStatus.Married,
        Gender = parts[2] == "m" ? Gender.Male : Gender.Female,
        District = int.Parse(parts[3])
    });
}

Upvotes: 1

KF2
KF2

Reputation: 10153

You can Make a structure for required information:

public struct Info
{
    public int Age;
    public string gender;
    public string status;
    public int district;
}

and inset data to your structure list:

  List<Info> info = new List<Info>();
    foreach (string line in File.ReadAllLines("census.txt"))
    {
        string[] parts = line.Split(',');

            info.Add(new Info() {Age=int.Parse(parts[0]), gender=parts[1], status=parts[2], district=int.Parse(parts[3]) });
    }

Now yo have a list of person information.

Upvotes: 0

Related Questions