2d array from string

J

Jase Schick

I know this might sound really lunk-headed but I'm stuck, I am! I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory then
I can adapt that.

An example would be using a stream of numbers to point to x,y coords.
Although this project really uses a large (80k) 1d array of hex numbers--
a XBM viewer. XBM graphics is C code so I figured it wouldn't be too hard
to work with it... hah hah Jase, not so easily...
 
B

Ben Pfaff

Jase Schick said:
I know this might sound really lunk-headed but I'm stuck, I am! I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory then
I can adapt that.

Do you have an example of what you want?
 
K

Keith Thompson

Jase Schick said:
I know this might sound really lunk-headed but I'm stuck, I am! I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory then
I can adapt that.

An example would be using a stream of numbers to point to x,y coords.
Although this project really uses a large (80k) 1d array of hex numbers--
a XBM viewer. XBM graphics is C code so I figured it wouldn't be too hard
to work with it... hah hah Jase, not so easily...

If you have an xbm file as input, then you have the vertical and
horizontal dimensions (in pixels) at the top of the file.

C array's aren't "first-class" types in a lot of ways. For example,
you can declare a fixed-size array easily enough:

int arr2d[100][200];

But if you don't know the dimensions at compile time, there's no good
way to allocate a dynamic 2-d array and use ordinary indexing on it
as you could for a constant-size array.

You can allocate a 1-dimensional array and do your own indexing
calculations; given x and y, compute the index in the 1-d array.

See also question 6.16 in the comp.lang.c FAQ, <http://c-faq.com/>.
Read all of section 6 while you're at it.
 
U

usenet

Jase Schick said:
I know this might sound really lunk-headed but I'm stuck, I am! I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory then
I can adapt that.
An example would be using a stream of numbers to point to x,y coords.
Although this project really uses a large (80k) 1d array of hex numbers--
a XBM viewer. XBM graphics is C code so I figured it wouldn't be too hard
to work with it... hah hah Jase, not so easily...

If you have an xbm file as input, then you have the vertical and
horizontal dimensions (in pixels) at the top of the file.

C array's aren't "first-class" types in a lot of ways.  For example,
you can declare a fixed-size array easily enough:

    int arr2d[100][200];

But if you don't know the dimensions at compile time, there's no good
way to allocate a dynamic 2-d array and use ordinary indexing on it
as you could for a constant-size array.

Except for this way (Iliffe structure):

int **arr2d;

arr2d = malloc( x_dimension * sizeof(int*) );
for (i=0; i < x_dimension; i++)
arr2d = malloc( y_dimension * sizeof(int) );

(error-checking omitted)

then just fire away:

arr2d[x1][y1] = foo;
bar = arr2d[x2][y2];


Or the other way, maybe more suited to the OP, where
you read the file data into a single memory block, then
set up the array of pointers to divide it up into slices
of equal length.

Regards,
Chris Noonan
 
S

Shao Miller

Keith said:
Jase Schick said:
I know this might sound really lunk-headed but I'm stuck, I am! I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory then
I can adapt that.

An example would be using a stream of numbers to point to x,y coords.
Although this project really uses a large (80k) 1d array of hex numbers--
a XBM viewer. XBM graphics is C code so I figured it wouldn't be too hard
to work with it... hah hah Jase, not so easily...

If you have an xbm file as input, then you have the vertical and
horizontal dimensions (in pixels) at the top of the file.

C array's aren't "first-class" types in a lot of ways. For example,
you can declare a fixed-size array easily enough:

int arr2d[100][200];

But if you don't know the dimensions at compile time, there's no good
way to allocate a dynamic 2-d array and use ordinary indexing on it
as you could for a constant-size array.

You can allocate a 1-dimensional array and do your own indexing
calculations; given x and y, compute the index in the 1-d array.

See also question 6.16 in the comp.lang.c FAQ, <http://c-faq.com/>.
Read all of section 6 while you're at it.
With C99, I rather enjoy pointers to arrays:
-----
#include <stdlib.h>
#include <stdio.h>

int main(void) {
static const int dims[2][2] = {
{ 3, 5 },
{ 4, 8 },
};
int dim;

for (dim = 0; dim < sizeof dims / sizeof *dims; dim++) {
int (*my_array)[dims[dim][0]][dims[dim][1]];
int i, j;

my_array = calloc(sizeof *my_array / sizeof **my_array,
sizeof **my_array);
if (!my_array) {
puts("Out of memory.");
return EXIT_FAILURE;
}
for (i = 0; i < sizeof *my_array / sizeof **my_array; i++) {
printf("{ ");
for (j = 0; j < sizeof **my_array / sizeof ***my_array; j++ ) {
printf("%d, ", (*my_array)[j]);
}
printf("}\n");
}
puts("---");
free(my_array);
}

return EXIT_SUCCESS;
}

-----

Or with "convenience" macros:
-----
#include <stdlib.h>
#include <stdio.h>

#define NUM_OF_ELEMENTS(array_) \
(sizeof (array_) / sizeof *(array_))
#define FOR_EACH_ELEMENT(index_, array_) \
for ((index_) = 0; (index_) < NUM_OF_ELEMENTS(array_); (index_)++)

int main(void) {
static const int dims[2][2] = {
{ 3, 5 },
{ 4, 8 },
};
int dim;

FOR_EACH_ELEMENT(dim, dims) {
#define MY_ARRAY (*my_array)
int MY_ARRAY[dims[dim][0]][dims[dim][1]];
int i, j;

my_array = calloc(NUM_OF_ELEMENTS(MY_ARRAY), sizeof MY_ARRAY[0]);
if (!&MY_ARRAY) {
puts("Out of memory.");
return EXIT_FAILURE;
}
FOR_EACH_ELEMENT(i, MY_ARRAY) {
printf("{ ");
FOR_EACH_ELEMENT(j, MY_ARRAY) {
printf("%d, ", MY_ARRAY[j]);
}
printf("}\n");
}
puts("---");
free(&MY_ARRAY);
#undef MY_ARRAY
}

return EXIT_SUCCESS;
}
 
M

Malcolm McLean

I know this might sound really lunk-headed but I'm stuck, I am! I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory then
I can adapt that.
Multi-dimensional arrays are a difficult feature of the C language.
The syntax for passing them around is over-complicated, and the fact
that the dimensions can't be changed dynamically means that they are
useless for most application areas where you'd think they would be
natural (eg images).

Just pad your string out so that it is reactangle of the appropriate
width. Then access the elements like this

str[y * width + x] = 'X';
 
B

Ben Bacarisse

Malcolm McLean said:
I know this might sound really lunk-headed but I'm stuck, I am! I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory then
I can adapt that.
Multi-dimensional arrays are a difficult feature of the C language.
The syntax for passing them around is over-complicated, and the fact
that the dimensions can't be changed dynamically means that they are
useless for most application areas where you'd think they would be
natural (eg images).

Just pad your string out so that it is reactangle of the appropriate
width. Then access the elements like this

str[y * width + x] = 'X';

This advice may be somewhat biased. You can "re-shape" an array quite
easily in C and if you use modern C99 the dimensions can be run-time
run-time. After

unsigned char (*reshaped)[width] = (void *)&one;

you can use reshaped[y][x] if you don't want to do the multiplication
every access.

It's a matter of opinion if this is over-complicated and useless, but
many programmers are quite happy with it.
 
S

Shao Miller

Jase said:
I know this might sound really lunk-headed but I'm stuck, I am! I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory then
I can adapt that.

An example would be using a stream of numbers to point to x,y coords.
Although this project really uses a large (80k) 1d array of hex numbers--
a XBM viewer. XBM graphics is C code so I figured it wouldn't be too hard
to work with it... hah hah Jase, not so easily...
If you essentially have an array of 'int' with the first two elements
specifying the dimensions, you can use something like this:

#include <stdlib.h>
#include <stdio.h>

#define NUM_OF_ELEMENTS(array_) \
(sizeof (array_) / sizeof *(array_))
#define FOR_EACH_ELEMENT(index_, array_) \
for ((index_) = 0; (index_) < NUM_OF_ELEMENTS(array_); (index_)++)

enum dimensions {
row_dim,
col_dim,
total_dims
};
typedef int int_arr_2d[total_dims];

static void print_array_is_safe(int_arr_2d array) {
#define my_array (*my_array)
int my_array[array[row_dim]][array[col_dim]] = (void *)(array +
total_dims);
int row, col;

FOR_EACH_ELEMENT(row, my_array) {
printf("{ ");
FOR_EACH_ELEMENT(col, my_array[row])
printf("%d, ", my_array[row][col]);
puts("}");
}
puts("---");
return;
#undef my_array
}

static void print_array(int_arr_2d array) {
if (!array || array[row_dim] == 0 || array[col_dim] == 0)
return;
print_array_is_safe(array);
return;
}

int main(void) {
/* test1 dimensions */
enum {
test1_rows = 3,
test1_cols = 5
};
/* test2 dimension */
enum {
test2_rows = 4,
test2_cols = 8
};
/* Two tests. */
static int test1[total_dims + test1_rows * test1_cols] =
{ test1_rows, test1_cols, 1, 1, 1 };
static int test2[total_dims + test2_rows * test2_cols] =
{ test2_rows, test2_cols, 2, 2, 2 };

/* Print them. */
print_array(test1);
print_array(test2);
return EXIT_SUCCESS;
}
 
J

Jase Schick

Hi guys

Sorry if my post was hard to follow. To clarify I've basically got a 1d
array/string and I need to get it into a 2-d array like x,y coordinates.

Vincenzo said:
Jase Schick wrote:
[...]
I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory
then I can adapt that.

Sorry, I can't understand what you mean. if you want to know how C
stores arrays in memory there is only one thing to know:

http://en.wikipedia.org/wiki/Row-major_order
 
B

Ben Bacarisse

Top posting is not the preferred style here. I've re-ordered your post.

Jase Schick said:
Vincenzo said:
Jase Schick wrote:
[...]
I can't,
for the life of me, figure out how to get a 2d array out of a linear
string/array. If I could figure out how the pc does arrays in memory
then I can adapt that.

Sorry, I can't understand what you mean. if you want to know how C
stores arrays in memory there is only one thing to know:

http://en.wikipedia.org/wiki/Row-major_order

Sorry if my post was hard to follow. To clarify I've basically got a 1d
array/string and I need to get it into a 2-d array like x,y coordinates.

There have been a couple of solutions posted already so it would
probably help if you said why they were not suitable or what it was
about them that you'd like to explained further.

Since you talk about "how the PC does it" I suspect that you might be
after a very specific kind of 2D data, not just a way treat your 1D
array is if it were 2D. If that is so, you might be better off posting
in a graphics group.
 
C

Chris Noonan

If you have an xbm file as input, then you have the vertical and
horizontal dimensions (in pixels) at the top of the file.
C array's aren't "first-class" types in a lot of ways.  For example,
you can declare a fixed-size array easily enough:
    int arr2d[100][200];
But if you don't know the dimensions at compile time, there's no good
way to allocate a dynamic 2-d array and use ordinary indexing on it
as you could for a constant-size array.

Except for this way (Iliffe structure):

int **arr2d;

arr2d = malloc( x_dimension * sizeof(int*) );
for (i=0; i < x_dimension; i++)
   arr2d = malloc( y_dimension * sizeof(int) );

(error-checking omitted)

then just fire away:

arr2d[x1][y1] = foo;
bar = arr2d[x2][y2];

Or the other way, maybe more suited to the OP, where
you read the file data into a single memory block, then
set up the array of pointers to divide it up into slices
of equal length.

Regards,
Chris Noonan


My apologies. Both techniques are in the FAQ section that
you referenced later in your post.

Regards,
Chris Noonan
 

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

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top