473,414 Members | 1,964 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,414 software developers and data experts.

file into dynamic arrays

I have two structures;

struct cordsys {
int y, x, length
};

struct provinces {
int number;
int type;
struct cordsys cord;
};

and a file that looks like:

1
68 78 83
69 78 87
70 78 89
71 78 91
72 78 93
73 77 95
1

2
110 77 180
111 77 182
112 77 184
113 76 186
114 76 188
115 76 189
116 76 191
117 76 192
2
.................

what i need to do is read the beginning number into provinces.number.
and read the next rows. with three numbers each. read into
provinces.cords.y provinces.cord.x provinces.cord.length

creating a new cord array (while keeping the old one) with each row.
when it hits a number that matches the beginning cord. i need it to add
a new province array (while keeping the old one)

i'm new to c so know nothing about memory management. not asking anyone
to do my work also. just need a detailed explanation of the concepts,
possibly functions, and a general idea. think who/what/where/why. thank
you.

Feb 17 '06 #1
8 2738
Steve Chow wrote:
I have two structures;

struct cordsys {
int y, x, length
};

struct provinces {
int number;
int type;
struct cordsys cord;
};

and a file that looks like:

1
68 78 83
69 78 87
<snip>
1

2
110 77 180
111 77 182
<snip>
2
................

what i need to do is read the beginning number into provinces.number.
and read the next rows. with three numbers each. read into
provinces.cords.y provinces.cord.x provinces.cord.length

creating a new cord array (while keeping the old one) with each row.
when it hits a number that matches the beginning cord. i need it to add
a new province array (while keeping the old one)

i'm new to c so know nothing about memory management. not asking anyone
to do my work also. just need a detailed explanation of the concepts,
possibly functions, and a general idea. think who/what/where/why. thank
you.


I suppose the thing to do is to break the problem into chunks. Ignore
the
memory management problem to begin with. Write a program to read a
single
province's worth of data into a fixed structure.Your struct provinces
isn't
going to hack it, is it? It only holds a single coordinate. perhaps an
array of
coordinates would be better. With provinces pointing to it. Consider:-

struct cordsys {
int y, x, length
};

struct provinces {
int number;
int type;
struct cordsys *cord; // pointer to coord_table
};

struct cordsys coord_table [64]; /* larger than expected number of
entries */

Then do the i/o stuff. Then read up on linked lists. Since you don't
know
how many cordinates or provinces there are in advance a linked lists
seems
a good choice. I cannot be certain as I don't know what you are going
to do
with the data...

So for i/o use fgets(), sscanf()
for memory allocation malloc(), free()

If you're still stuck you need to explain which bit you have a problem
with.
--
Nick Keighley

Feb 17 '06 #2

Steve Chow wrote:

<snip>
creating a new cord array (while keeping the old one) with each row.
when it hits a number that matches the beginning cord. i need it to add
a new province array (while keeping the old one)


<snip>

you might take a look at realloc() as well
--
Nick Keighley

Feb 17 '06 #3
On 17 Feb 2006 00:20:19 -0800, "Steve Chow" <ms*********@hotmail.com>
wrote:
I have two structures;

struct cordsys {
int y, x, length
};

struct provinces {
int number;
int type;
struct cordsys cord;
};

and a file that looks like:

1
68 78 83
69 78 87
70 78 89
71 78 91
72 78 93
73 77 95
1

2
110 77 180
111 77 182
112 77 184
113 76 186
114 76 188
115 76 189
116 76 191
117 76 192
2
................

what i need to do is read the beginning number into provinces.number.
and read the next rows. with three numbers each. read into
provinces.cords.y provinces.cord.x provinces.cord.length

creating a new cord array (while keeping the old one) with each row.
cord is not an array. It is an instance of a single struct cordsys
inside a struct provinces. From your description, I believe you want
an array of such cordsys in each struct provinces.

If the number of elements of this array is constant across all
struct provinces, then simply declare it an array in the declaration
of struct provinces.

If the number of elements varies among the different
provinces, then change cord from a struct cordsys to a pointer to
struct cordsys. You can then allocate memory for the pointer to point
to and also reallocate when necessary.
when it hits a number that matches the beginning cord. i need it to add
a new province array (while keeping the old one)
If you don't know how many struct provinces you will need, then define
a pointer to struct provinces and allocate memory for it to point to.
As above, you can reallocate memory when the need arises.

i'm new to c so know nothing about memory management. not asking anyone
to do my work also. just need a detailed explanation of the concepts,
possibly functions, and a general idea. think who/what/where/why. thank
you.


The memory allocation functions are malloc and realloc. You should
also free (using the function of that name) any memory allocated when
you are done with it.
Remove del for email
Feb 18 '06 #4
i'm sorry it was a misprint. i meant *cords.
here is my current code. can't seem to figure out why it's crashing.

--NOTE; i changed the block indentifer from the file from an int to
array as well as some other things. I also don't intend to keep the
while(1) just there for testing

typedef struct
{
int y;
int xl;
int xr;
}Cords;

typedef struct
{
char *name;
char type;

Cords *cords;
}State;

void loadmap(State *t_states)
{
FILE *mapfile =
fopen("map.tbl", "r");

Cords t_cords;

int s_s = 0, s_c = 0;

fscanf(mapfile, "%s", &t_states[s_s].name);

t_states[s_s].cords =
malloc(sizeof(Cords)*1);

while(1)
{
if(fscanf(mapfile, "%d %d %d", &t_states[s_s].cords[s_c].y,
&t_states[s_s].cords[s_c].xl, &t_states[s_s].cords[s_c].xr)
< 3)
{
t_states = realloc(t_states, sizeof(State)*1);
fscanf(mapfile, "%s", &t_states[++s_s].name);
s_c = 0;
}

printf("%d %d %d\n", t_states[s_s].cords[s_c].y,
t_states[s_s].cords[s_c].xl, t_states[s_s].cords[s_c].xr);

t_states[s_s].cords =
realloc(t_states[s_s].cords, sizeof(Cords)*1);

s_c++;
}
}

Feb 18 '06 #5
sorry meant to include the actual error

268 232 258
269 234 254
270 238 252
875704842 808727840 892679456 <--- Right where it hits the string and
is supposed to allocate a new state
*** glibc detected *** realloc(): invalid pointer: 0xb7f628dd ***
Aborted

Feb 18 '06 #6
Steve Chow wrote:
i'm sorry it was a misprint. i meant *cords.
*what* was a misprint? If you need to refer to a previous post then
put it in the post- as I have done.
here is my current code. can't seem to figure out why it's crashing.
nor can I. Could you post a complete program?
--NOTE; i changed the block indentifer from the file from an int to
array as well as some other things. I also don't intend to keep the
while(1) just there for testing

typedef struct
{
int y;
int xl;
int xr;
}Cords;

typedef struct
{
char *name;
char type;

Cords *cords;
}State;

void loadmap(State *t_states)
{
we don't know what t_states is pointing at. Did you allocate space
for name?
FILE *mapfile =
fopen("map.tbl", "r");
always check the return value of fopen()
Cords t_cords;

int s_s = 0, s_c = 0;

fscanf(mapfile, "%s", &t_states[s_s].name);
fscanf() is potentially dangerous. Did you really mean to pass a
char**?
Remove the &. It is good practice to check the return value.
t_states[s_s].cords =
malloc(sizeof(Cords)*1);
always check the return value of malloc(). Why *1?
while(1)
{
if(fscanf(mapfile, "%d %d %d", &t_states[s_s].cords[s_c].y,
&t_states[s_s].cords[s_c].xl, &t_states[s_s].cords[s_c].xr)
< 3)
{
why <3? If I remember correctly fscanf() returns the number of items
read. So you only reallocate when you have a failure?
t_states = realloc(t_states, sizeof(State)*1);
and if realloc() fails? You should assign to a temporary, check for
NULL then assign. This function can't modify t_states as far as the
caller
is concerned because it's only a State*. It needs to be a State**. Why
*1?
Won't this always allocate a block of the same size? I think you need
to
re-read the realloc() documentation.
fscanf(mapfile, "%s", &t_states[++s_s].name);
s_c = 0;
}

printf("%d %d %d\n", t_states[s_s].cords[s_c].y,
t_states[s_s].cords[s_c].xl, t_states[s_s].cords[s_c].xr);
how many times does it loop?
t_states[s_s].cords =
realloc(t_states[s_s].cords, sizeof(Cords)*1);
again all the things I said before about realloc()
s_c++;
}
}


fix the things above. Work out how to terminate the loop. Add trace
prints so you can see what it's doing. If you still have a problem
post a ***short but complete program***
--
Nick Keighley

Testing can show the presense of bugs, but not their absence.
-- Dijkstra

Feb 18 '06 #7
On Fri, 17 Feb 2006 23:28:34 -0800, Steve Chow wrote:
i'm sorry it was a misprint. i meant *cords. here is my current code.
can't seem to figure out why it's crashing.
It crashed because you were lucky this time. Had you been unlucky, you
would not have discovered that you program is wrong until much later!
typedef struct
{
int y;
int xl;
int xr;
}Cords;

typedef struct
{
char *name;
char type;

Cords *cords;
}State;

void loadmap(State *t_states)
{
FILE *mapfile =
fopen("map.tbl", "r");

Cords t_cords;

int s_s = 0, s_c = 0;

fscanf(mapfile, "%s", &t_states[s_s].name);
1. name is an uninitialised pointer to char. Where is the string supposed
to go? You have not allocated any memory to store it.

2. Don't use fscanf's %s format because it can read an uncontrolled number
of characters and might thus overflow any buffer you read into. Use fgets
or at the very least put maximun size into the format.

t_states[s_s].cords =
malloc(sizeof(Cords)*1);
You allocate space for one set of Cords but this:
while(1)
suggests that you plan to read lots. You have nowhere to put them.
{
if(fscanf(mapfile, "%d %d %d", &t_states[s_s].cords[s_c].y,
&t_states[s_s].cords[s_c].xl, &t_states[s_s].cords[s_c].xr) < 3)
{
t_states = realloc(t_states, sizeof(State)*1); fscanf(mapfile, "%s",
&t_states[++s_s].name); s_c = 0;
}

printf("%d %d %d\n", t_states[s_s].cords[s_c].y,
t_states[s_s].cords[s_c].xl, t_states[s_s].cords[s_c].xr);

t_states[s_s].cords =
realloc(t_states[s_s].cords, sizeof(Cords)*1);

s_c++;
}
}


I would suggest some more functional decomposition. Write a function to
safely read a name. Use a large fixed-size buffer for example and then
return a copy of the (shorter) string actually read. Write one that can
fill a Cords structure. Write another that can read lots of Cords and
return a copy of the array of Cords actually seen and so one. Test each
one really well before moving on.

If you don't like the idea of copying like this then you will either need
to read your data twice (to count things first) or use a structure that
can grow like a linked list.

--
Ben.

Feb 18 '06 #8
Thanks to everyone that posted/helped. Everything works fine now.

Feb 18 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: meyousikmann | last post by:
The following code just sets up and fills a dynamic array of integers. #include <cstdlib> int main() { int* intArray = NULL; int count; count = 20;
4
by: Scott Lyons | last post by:
Hey all, Can someone help me figure out how to pass a dynamic array into a function? Its been giving me some trouble, and my textbook of course doesnt cover the issue. Its probably something...
11
by: fivelitermustang | last post by:
Actually, how would I go about allocating a four-dimensional dynamic array? I only know how to make two dimensional dynamic arrays: double **v; v = new double*; for (int i=0; i<C; i++) { v =...
6
by: Materialised | last post by:
Hi Everyone, I apologise if this is covered in the FAQ, I did look, but nothing actually stood out to me as being relative to my subject. I want to create a 2 dimensional array, a 'array of...
3
by: genc ymeri | last post by:
Hi, What can I use in C# for dynamic arrays ???? I have some records (struts in ..Net) and want to store them in a dynamic "arrays" or object list. I noticed the in C# arrays' length can't be...
4
by: learnfpga | last post by:
Here is a little code I wrote to add the numbers input by the user.....I was wondering if its possible to have the same functionality without using dynamic arrays.....just curious..... ...
3
by: repairman2003 | last post by:
I'm having some trouble with poitners and dynamic arrays (a matrix). Given this function I have a few questions. void func(int* mat, int rows, int columns, char* out) { ... }
1
by: KioKrofov | last post by:
Hello, I am trying to find out how Dynamic Arrays are actually stored in memory. Really, I want to know how Vectors are stored in memory, but I deduce they are stored the same way. If you...
2
by: headware | last post by:
Do dynamic arrays declared using ReDim have to be freed? I assume that if it's an array of dynamically created objects (e.g. Scripting.Dictionary), each one of those objects will have to be set to...
4
by: Sunny | last post by:
Hi, Is there a way in javascript to create Dynamic arrays or arrays on fly. Something Like: var "ptsgN"+sd = new Array(); Here sd is incrementing by 1. I have lots of data that I am...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.