HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Census data from file input (text)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
filecensustextinputfromdata

Problem

The program takes census data from a text file in the format age, gender, marital status, district. It then gives a list of residents by district (there are 22) and by 5 age groups. Any suggestions for improvement?

The only topics we have covered so far in class are methods, decisions, looping, and arrays.

```
static void Main(string[] args)
{
FileStream fStream = new FileStream("test.txt", FileMode.Open, FileAccess.Read);
StreamReader inFile = new StreamReader(fStream);

string inputRecord = "";
string[] fields;
int[] ageData = new int[1000];
string[] genderData = new string[1000];
string[] maritalData = new string[1000];
int[] districtData = new int[1000];
int[] countDist = new int[23];
int[] ageGroup = new int[5];

inputRecord = inFile.ReadLine();

int i = 0;
while (inputRecord != null)
{
fields = inputRecord.Split(',');

ageData[i] = int.Parse(fields[0]);
genderData[i] = fields[1];
maritalData[i] = fields[2];
districtData[i] = int.Parse(fields[3]);

if (ageData[i] > 0 && ageData[i] 18 && ageData[i] 30 && ageData[i] 45 && ageData[i] = 65)
{
ageGroup[4] = ageGroup[4] + 1;
}

i++;

inputRecord = inFile.ReadLine();
}
Console.WriteLine("This Program takes census data from a file and lists residents by age group and district");
Console.WriteLine("Please ensure the file is formatted correctly! age,gender (M/F),marital status (M/S), and district");
for (int x = 1; x <= 22; x++)
for (int y = 0; y < districtData.Length; y++)
if (districtData[y] == x)
countDist[x]++;

for (int x = 1; x <= 22; x++)
Console.WriteLine("District " + x + " has " + countDist[x] + " citizens");

Console.WriteLine("-

Solution

user2023861 covers a lot of good ground, so I just have a couple more things to add.

First, instead of using parallel arrays, you might want to consider using a collection container like a List and filling it with objects. Each line appears to a distinct record with a set of properties, so I would make them a simple Class:

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


That way, you don't have to hard code the size of the arrays that you are using, and you don't have to do any work to keep the related pieces of the record in synch (think what would happen if one of the arrays got sorted and the rest didn't).

Then, in your parser you can create objects for each record:

var records = new List();
var inputRecord = inFile.ReadLine();

while (inputRecord != null)
{
    var fields = inputRecord.Split(',');
    var currentRecord = new Record()
    {
        Age = int.Parse(fields[0]),
        Gender = fields[1],
        MaritalStatus = fields[2],
        District = int.Parse(fields[3])
    };

    records.Add(currentRecord);
    //...
}


You need to remember to dispose of your FileStream and StreamReader if you are accessing them this way. The easier and safer way to do this is with the using syntax, which will close and dispose of them at the ending braces. I'd get into the habit of using this with any object with a .Dispose() method.

using (var fStream = new FileStream("test.txt", FileMode.Open, FileAccess.Read))
{
    using (var inFile = new StreamReader(fStream))
    {
        //Work with the file here
        //...
    } //inFile.Dispose() happens here automatically.
} //fStream.Dispose() happens here automatically.


This code...

for (int x = 1; x <= 22; x++)
        for (int y = 0; y < districtData.Length; y++)
            if (districtData[y] == x)
                countDist[x]++;


...is begging for braces to make it easier to read. It also help avoid potential errors.

Code Snippets

public class Record
{
    public int Age { get; set; }
    public string Gender { get; set; }
    public string MaritalStatus { get; set; }
    public int District { get; set; }
}
var records = new List<Record>();
var inputRecord = inFile.ReadLine();

while (inputRecord != null)
{
    var fields = inputRecord.Split(',');
    var currentRecord = new Record()
    {
        Age = int.Parse(fields[0]),
        Gender = fields[1],
        MaritalStatus = fields[2],
        District = int.Parse(fields[3])
    };

    records.Add(currentRecord);
    //...
}
using (var fStream = new FileStream("test.txt", FileMode.Open, FileAccess.Read))
{
    using (var inFile = new StreamReader(fStream))
    {
        //Work with the file here
        //...
    } //inFile.Dispose() happens here automatically.
} //fStream.Dispose() happens here automatically.
for (int x = 1; x <= 22; x++)
        for (int y = 0; y < districtData.Length; y++)
            if (districtData[y] == x)
                countDist[x]++;

Context

StackExchange Code Review Q#85435, answer score: 5

Revisions (0)

No revisions yet.