another shot at this

J

John Salerno

private static void InitializeArrays()
{
FileStream stream = new FileStream(path, FileMode.Open,
FileAccess.Read);
StreamReader readSwitches = new StreamReader(stream);
int i = 0;

using (readSwitches)
{
string row = readSwitches.ReadToEnd();
string[] switches = row.Split('|');

string[, ,] panelOne = FillPanel(switches);
}
}

private static string[, ,] FillPanel(string[] switches)
{
string[, ,] panel;

for (int z = 0; z < 8; z++)
{
for (int x = 0; x < 2; x++)
{
for (int y = 0; y < 10; y++)
panel[x, y, z] = switches[i++];
}
}

return panel;
}



Ok, I made it to where the switches array contains all the information
that I then need to put into the panel arrays. Each panel array (four of
them) will consist of 8 different 2x10 arrays. I'm still trying to
figure out a good way to fill them up. The above code won't compile, but
I feel like I'm getting closer. I'd appreciate any comments.
 
M

Marcus Andrén

I replied to this in another post, but since you posted a more
complete code sample, here is my reply.

static string[][,,] panels = new string[4][,,];
// or
// string[,,] panelOne;
// string[,,] panelTwo;
// ...

private static void InitializeArrays()
{
// Streamreader has an overload that takes a path, so there is
// no need to first get the filestream.
using(StreamReader readSwitches = new StreamReader(path))
{
string completeFile = readSwitches.ReadToEnd();
string[] switches = completeFile.Split('|');

if(switches.Length != 8*2*10*4)
throw new Exception("Invalid data file.");

panels[0] = FillPanel(switches,0);
panels[1] = FillPanel(switches,8*2*10);
panels[2] = FillPanel(switches,8*2*10*2);
panels[3] = FillPanel(switches,8*2*10*3);
// or
// panelOne = FillPanel(switches,0);
// panelTwo = FillPanel(switches,8*2*10);
// ...
}
}

private static string[, ,] FillPanel(string[] switches,int startIndex)
{
string[,,] panel = new string[2,10,8];
for (int z = 0; z < 8; z++)
for (int x = 0; x < 2; x++)
for (int y = 0; y < 10; y++)
panel[x, y, z] = switches[startIndex++];
return panel;
}
 
J

John Salerno

Marcus said:
// Streamreader has an overload that takes a path, so there is
// no need to first get the filestream.

I created the filestream because I wanted to make the file readonly, but
I guess if I don't do any explicit writing, it will effectively be a
readonly file anyway, right? (It's a text file I created filled with 0s
and 1s. Each line contains 20 digits, and there are 32 lines, so it's a
very rigid use of the file I have in mind.)
private static string[, ,] FillPanel(string[] switches,int startIndex)
{
string[,,] panel = new string[2,10,8];
for (int z = 0; z < 8; z++)
for (int x = 0; x < 2; x++)
for (int y = 0; y < 10; y++)
panel[x, y, z] = switches[startIndex++];
return panel;
}

Ah! Passing in a startIndex was what I was trying to figure out! This
helps a lot!

Now just one more question: Should I even put all the panels in one big
array? Or would it be okay to have four separate arrays? I was thinking
(as I posted in another thread, sorry!) that I could have four jagged
arrays, each representing one panel, and each containing 8 other arrays
for the 8 switches. Is it possible to have an array like string[][][,,]?
That would let me access a specific panel, switch, and position in the
switch. If that's not possible, then I'm thinking it might be better not
to use one array for all four panels, because it won't be as easy to
access each switch that way.
 
J

John Salerno

Ok, my new and improved version:

private static void InitializeArrays()
{
//FileStream stream = new FileStream(path, FileMode.Open,
FileAccess.Read);
//StreamReader readSwitches = new StreamReader(stream);

using (StreamReader readSwitches = new StreamReader(path))
{
string[] allSwitchValues =
readSwitches.ReadToEnd().Split('|');

string[][,] panelOne = FillPanel(allSwitchValues, 0);
string[][,] panelTwo = FillPanel(allSwitchValues, 8 * 2
* 10);
string[][,] panelThree = FillPanel(allSwitchValues, 8 *
2 * 10 * 2);
string[][,] panelFour = FillPanel(allSwitchValues, 8 *
2 * 10 * 3);
}
}

private static string[][,] FillPanel(string[] switches, int
startIndex)
{
string[][,] panel = new string[8][,];

for (int i = 0; i < 8; i++)
for (int x = 0; x < 2; x++)
for (int y = 0; y < 10; y++)
panel[x, y] = switches[startIndex++];

return panel;
}


I think it looks good, but who knows! :)
 
J

Jon Skeet [C# MVP]

John Salerno said:
John said:
panel[x, y] = switches[startIndex++];


This line throws an exception:

Object reference not set to an instance of an object.


Yes - you've created an array of multi-dimensional string arrays, but
you haven't populated it.

In the outermost loop, you need something like:

panel = new string[2,10];
 
J

John Salerno

Jon said:
Yes - you've created an array of multi-dimensional string arrays, but
you haven't populated it.

In the outermost loop, you need something like:

panel = new string[2,10];


That makes sense. Last night I was thinking about this some more, and I
thought maybe the problem was this:

string[][,] panelOne = FillPanel(allSwitchValues, 0);
string[][,] panelTwo = FillPanel(allSwitchValues, 8 * 2 * 10);
string[][,] panelThree = FillPanel(allSwitchValues, 8 * 2 * 10 * 2);
string[][,] panelFour = FillPanel(allSwitchValues, 8 * 2 * 10 * 3);

Should each of those arrays first be created like this:

string[][,] panelOne = new string[8][,]
//panelOne[0] = new string[2, 10] //do i need this first?
panelOne[0] = FillPanel(etc...)

I guess I'm a little confused about how much needs to be initialized first.
 
J

John Salerno

Jon said:
Yes - you've created an array of multi-dimensional string arrays, but
you haven't populated it.

In the outermost loop, you need something like:

panel = new string[2,10];


Well, that worked, of course! Thank you! My arrays are finally filled!

Now I notice when I try to access the arrays, they are out of scope
because I'm no longer working within the using block. Is there a proper
way to write a using block so that I can still use those arrays later? I
changed it to this and it works:

StreamReader readSwitchValues = new StreamReader(path);

string[] allSwitchValues = readSwitchValues.ReadToEnd().Split('|');
readSwitchValues.Close();

string[][,] panelOne = FillPanel(allSwitchValues, 0);
string[][,] panelTwo = FillPanel(allSwitchValues, 8 * 2 * 10);
string[][,] panelThree = FillPanel(allSwitchValues, 8 * 2 * 10 * 2);
string[][,] panelFour = FillPanel(allSwitchValues, 8 * 2 * 10 * 3);
 
J

Jon Skeet [C# MVP]

John Salerno said:
In the outermost loop, you need something like:

panel = new string[2,10];


Well, that worked, of course! Thank you! My arrays are finally filled!

Now I notice when I try to access the arrays, they are out of scope
because I'm no longer working within the using block. Is there a proper
way to write a using block so that I can still use those arrays later?


Declare them before the using block.
I changed it to this and it works:

StreamReader readSwitchValues = new StreamReader(path);

string[] allSwitchValues = readSwitchValues.ReadToEnd().Split('|');
readSwitchValues.Close();

string[][,] panelOne = FillPanel(allSwitchValues, 0);
string[][,] panelTwo = FillPanel(allSwitchValues, 8 * 2 * 10);
string[][,] panelThree = FillPanel(allSwitchValues, 8 * 2 * 10 * 2);
string[][,] panelFour = FillPanel(allSwitchValues, 8 * 2 * 10 * 3);

If an exception is thrown while you're reading, you won't be closing
the stream. Just declare the variables outside the using statement and
it'll be fine.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top