user3235894
user3235894

Reputation: 1

Read .csv file and store it in an array?

I am working on an assignment which stores data from .csv file into array. I have used for(int i = 0; i < data.Length; i++), but i++ is unreachable. Have a look on the code you will get to know. The problem is in storing only perhaps. Help me if you can.

Thanks

static void Load(string[] EmployeeNumbers, string[] EmployeeNames, string[] RegistrationNumbers, float[] EngineCapacityArray,
        int[] StartKilometresArray, int[] EndKilometresArray, string[] TripDescriptions, bool[] PassengerCarriedArray,
        ref int NextAvailablePosition, ref int RecordCount, ref int CurrentRecord)
    {
        string str = "";
        FileStream fin;
        string[] data;
        bool tval = false;
        // Open the input file
        try
        {
            fin = new FileStream("carallowance.csv", FileMode.Open);
        }
        catch (IOException exc)
        {
            Console.WriteLine(exc.Message);
            return;
        }
        // Read each line of the file
        StreamReader fstr_in = new StreamReader(fin);
        try
        {
            while ((str = fstr_in.ReadLine()) != null)
            {
                // Separate the line into the name and age
                data = str.Split(';');
                if (data.Length == 8)
                {
                    Console.WriteLine("Error: Could not load data from the file. Possibly incorrect format.");
                }
                for (int i = 0; i < data.Length; i++)
                {
                    EmployeeNumbers[NextAvailablePosition] = data[0];
                    EmployeeNames[NextAvailablePosition] = data[1];
                    RegistrationNumbers[NextAvailablePosition] = data[2];
                    tval = float.TryParse(data[3], out EngineCapacityArray[NextAvailablePosition]);
                    tval = int.TryParse(data[4], out StartKilometresArray[NextAvailablePosition]);
                    tval = int.TryParse(data[5], out EndKilometresArray[NextAvailablePosition]);
                    TripDescriptions[NextAvailablePosition] = data[6];
                    tval = bool.TryParse(data[7], out PassengerCarriedArray[NextAvailablePosition]);

                    CurrentRecord = NextAvailablePosition;
                    NextAvailablePosition++;
                    RecordCount++;
                    Console.WriteLine("Your file is sucessfully loaded.");

                    break;
                }
            }
        }
        catch (IOException exc)
        {
            Console.WriteLine(exc.Message);
        }
        // Close the file
        fstr_in.Close();
    }

Upvotes: 0

Views: 1720

Answers (4)

Steven Evers
Steven Evers

Reputation: 17226

Perhaps the code review stackexchange would be better. There's a number of issues here.

First we can simplify using a framework callto File.ReadAllLines(...). That will give you a sequence of all lines in the file. Then you want to transform that into a sequence of arrays (split on ','). That's straightforward:

var splitLines = File.ReadAllLines("\path")
                     .Select(line => line.Split(new char[] { ',' }));

Now you can just iterate over splitLines with a foreach.

(I do notice that you seem to be setting values into the arrays that are passed in. Try to not get into the habit of doing that. These kinds of side effects and abuse of reference params is prone to becoming very brittle.)

Then this seems very odd:

if (data.Length == 8)
{
    Console.WriteLine("...");
}

I suspect that you just have a typo in your comparison operator (should be !=). If you don't care about writing to the console on bad data, you can simply just filter out the bad data after the transformation. That looks like:

var splitLines = File.ReadAllLines("\path")
                     .Select(line => line.Split(new char[] { ',' }))
                     .Where(data => data.Length == 8);

Now recall that [int/float].TryParse(s, out v) will set v to be the value that was parsed, or the default value for the type, and return true if the parse was successful. That "or default" is important here. That means that you're stuffing bad/invalid values if they can't be parsed, and you're doing nothing with tval.

Instead of all of that, consider an object/type that represents a record from your dataset. It looks like you're trying to track employee mileage from a csv table. That looks something like:

public class MileageRecord
{
    public string Name { get; set; }
    /* More properties */
    public MileageRecord FromCSV(string[] data)
    {
        /* try parsing, if not then log errs to file and return null */
    }
}

Now you've gotten rid of all of your side effects and the whole thing is cleaner. Loading all this data from file is as straightforward as this:

public static IEnumerable<MileageRecord> Load()
{
    return File.ReadAllLines("\path")
               //.Skip(1) // if first line of the file is column headers
               .Select(line => line.Split(new char[] { ',' }))
               .Where(data => data.Length == 8)
               .Select(data => MileageRecord.FromCSV(data))
               .Where(mileage => mileage != null);
}

Upvotes: 1

Sudhakar Tillapudi
Sudhakar Tillapudi

Reputation: 26209

Problem : you are supposed to add break statement inside the if condition(which is inside the while loop) , so that if the data Length does not match with 8 then it will break/come out from loop. but you have mistakenly added break inside the for-loop.that why it only executed for 1st time and comesout of the loop.

Solution : Move the break statement from for loop to if-blcok inside the while loop.

Try This:

Step 1: Remove the break statement from for-loop.

                CurrentRecord = NextAvailablePosition;
                NextAvailablePosition++;
                RecordCount++;
                Console.WriteLine("Your file is sucessfully loaded.");

               // break; //move this statement to inside the if block

Step 2: place the break statement in if-block inside while loop.

          if (data.Length == 8)
            {
                Console.WriteLine("Error: Could not load data from the file. Possibly incorrect format.");
                break;
            }

Suggestion : you can re-write your code using File.ReadAllLines() method to avoid the complexity as below :

static void Load(string[] EmployeeNumbers, string[] EmployeeNames, string[] RegistrationNumbers, float[] EngineCapacityArray,
  int[] StartKilometresArray, int[] EndKilometresArray, string[] TripDescriptions, bool[] PassengerCarriedArray,
  ref int NextAvailablePosition, ref int RecordCount, ref int CurrentRecord)
  {
           string str = "";        
           string[] data;
           bool tval = false;
           String [] strLines=File.ReadAllLines("carallowance.csv");
           for(int i=0;i<strLines.Length;i++)
           {
            str=strLines[i];
            data = str.Split(';');
            if (data.Length == 8)
            {
                Console.WriteLine("Error: Could not load data from the file. Possibly incorrect format.");
                break;
            }//End of if block
            else
            {
                EmployeeNumbers[NextAvailablePosition] = data[0];
                EmployeeNames[NextAvailablePosition] = data[1];
                RegistrationNumbers[NextAvailablePosition] = data[2];
                tval = float.TryParse(data[3], out EngineCapacityArray[NextAvailablePosition]);
                tval = int.TryParse(data[4], out StartKilometresArray[NextAvailablePosition]);
                tval = int.TryParse(data[5], out EndKilometresArray[NextAvailablePosition]);
                TripDescriptions[NextAvailablePosition] = data[6];
                tval = bool.TryParse(data[7], out PassengerCarriedArray[NextAvailablePosition]);

                CurrentRecord = NextAvailablePosition;
                NextAvailablePosition++;
                RecordCount++;                    
             } //End of else block
            } //End of for loop
           Console.WriteLine("Your file is sucessfully loaded.");
   } //End of function

Upvotes: 0

Paweł Bejger
Paweł Bejger

Reputation: 6366

This piece of code:

            NextAvailablePosition++;
            RecordCount++;
            Console.WriteLine("Your file is sucessfully loaded.");

            break; // <-- this instruction
        }

Takes you out of the for loop without the possibility to increment i value.

Upvotes: 0

Allan Elder
Allan Elder

Reputation: 4104

It's unreachable because of the break; at the end of the loop. That forces the for loop to stop executing after the first time around. If you run this in a console project, it'll only put out a 0.

    private static void Main(string[] args)
    {
        for (int i = 0; i < 2; i++)
        {
            Console.WriteLine(i.ToString());
            break;
        }
    }

Upvotes: 1

Related Questions