473,465 Members | 1,395 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

array of structures.

I have structures like this in my program -

typedef vector vectorstruct
{
double x, y,z;
} vector;

typedef struct verticesstruct
{
vector v;
} vertex; /*a vertex is a vector */

typedef struct trianglestruct
{
int v0,v1, v2;
}triangle;

typedef struct objectstruct
{
int nvert;
int ntri;
vertex *vert;
triangle *tri;
}object;

................
...............

later somewhere in the program i have a statement like this -

object *obj;

obj->vert = malloc( nvert * sizeof(vertex)); /* Creating an array of
vertices */

obj->tri = malloc(ntri * sizeof(triangle));

for(i=0;i<obj->nvert; i++)/* trying to take input for each vertex
which has x, y, z components as it is a vector*/
scanf("%f %f %f", &obj->vert[i].x, &obj->vert[i].y, &obj->vert[i].z);

^^^^^^^^ is this above notation of creating an array and then
accessing the elements correct ??
later on i also do this -

for(i=0;i<obj->ntri;i++)
scanf("%d %d %d", &obj->tri[i].v0, &obj->tri[i].v1, &obj->tri[i].v2);
Mar 9 '08 #1
13 1754
On Sun, 09 Mar 2008 06:45:54 -0700, Cell wrote:
I have structures like this in my program -

typedef vector vectorstruct
Syntax error. "vector" should be "struct". Please try to copy and paste
from code you've actually tried to use as much as possible, so that errors
such as these can be avoided.
{
double x, y,z;
} vector;

typedef struct verticesstruct
{
vector v;
This is fine, but...
} vertex; /*a vertex is a vector */
....vertex is a structure with one member. This member is named "v", and
has type vector.
typedef struct trianglestruct
{
int v0,v1, v2;
}triangle;
Okay, so a triangle has three members v0, v1, and v2.
typedef struct objectstruct
{
int nvert;
int ntri;
vertex *vert;
triangle *tri;
}object;

...............
..............

later somewhere in the program i have a statement like this -

object *obj;

obj->vert = malloc( nvert * sizeof(vertex)); /* Creating an array of
vertices */
What is nvert? You haven't declared it. Did you mean obj->nvert? Please
try to copy and paste from code you've actually tried to use as much as
possible, so that errors such as these can be avoided.
obj->tri = malloc(ntri * sizeof(triangle));
See above.
for(i=0;i<obj->nvert; i++)/* trying to take input for each vertex which
has x, y, z components as it is a vector*/ scanf("%f %f %f",
&obj->vert[i].x, &obj->vert[i].y, &obj->vert[i].z);
A vertex has one member. This member has a name "v". A vertex does not
have any members x, y, or z. A vector does.
^^^^^^^^ is this above notation of creating an array
The array creation is okay.
and then accessing
the elements correct ??
The access is not okay.
later on i also do this -

for(i=0;i<obj->ntri;i++)
scanf("%d %d %d", &obj->tri[i].v0, &obj->tri[i].v1, &obj->tri[i].v2);
A triangle has members v0, v1, and v2, and you're accessing members v0,
v1, and v2. Not surprisingly, this works. :)
Mar 9 '08 #2
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct vectorstruct
{
double x, y, z;
}vector;

typedef struct verticesstruct
{
vector v;
}vertex;

typedef struct trianglestruct
{
int v0, v1, v2;
}triangle;

typedef struct objectstruct
{
int nvert;
int ntri;
vertex *vert;
triangle *tri;
}object;

int read_dat_file( char * dat_file, object * obj )
{

FILE *fp;
int i;

if(!(fp = fopen(dat_file,"r")))
return -1;
while(fp!=NULL)
{
fscanf(fp, "%d %d", &(obj->nvert), &(obj->ntri));
printf("\n%d %d", obj->nvert, obj->ntri);

obj->vert= malloc(obj->nvert * sizeof(vertex));

obj->tri = malloc(obj->ntri * sizeof(triangle));

for(i=0;i<obj->nvert;i++)
{
fscanf(fp, "%f %f %f",&(obj->vert[i].v.x), &(obj->vert[i].v.y), &(obj-
>vert[i].v.z));
printf("%f %f %f", obj->vert[i].v.x, obj->vert[i].v.y, obj-
>vert[i].v.z);
}

for(i=0;i<obj->ntri;i++)
{
fscanf(fp, "%d %d %d",&(obj->tri[i].v0), &(obj->tri[i].v1), &(obj-
>tri[i].v2));
printf("%d %d %d", obj->tri[i].v0, obj->tri[i].v1, obj->tri[i].v2);
}

}
return 1;
}

int main()
{

object *obj;
char *s;
clrscr();
obj = malloc(sizeof(object));
strcpy(s, "sphere.dat");
if(!(read_dat_file(s , obj)))
printf("unsuccessful");
return 0;

}


Mar 9 '08 #3
the sphere.dat file contains description of a sphere which has been
triangulated..

the first line of sphere.dat is something like this -

nvert ntri /*the number of vertices, number of triangles */

in the case of a sphere, nvert = 602, ntri = 1200

from the second line we have coordinates of each vertex. A combination
of 3 vertices forms a triangle.

x1 y1 z1
x2 y2 z2
.........
.........
.........
xnvert ynvert znvert

I stored this in a list of vertices. Hence the vert pointer in object
structure. Similarly there is a tri pointer which can be used for
dynamically creating a list of triangles.

After the n vertices, we have the description of triangles (1200
entries)

12 0 1
3 4 5
23 8 5
.......
.......
.......

Those numbers are basically indices to vertex list. So 12 indicates
the 12th vertex or 12 the entry in the vertex list. 0 indicates
0th(first entry) in the vertex list 1 indicates 1st element of vertex
list. So basically a combination of 3 vertices is forming a triangle.
And this is what Im trying to read from the file and print.
Mar 9 '08 #4
Cell wrote:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct vectorstruct
{
double x, y, z;
}vector;

typedef struct verticesstruct
{
vector v;
}vertex;

typedef struct trianglestruct
{
int v0, v1, v2;
}triangle;

typedef struct objectstruct
{
int nvert;
int ntri;
vertex *vert;
triangle *tri;
}object;

int read_dat_file( char * dat_file, object * obj )
{

FILE *fp;
int i;

if(!(fp = fopen(dat_file,"r")))
return -1;
while(fp!=NULL)
{
fscanf(fp, "%d %d", &(obj->nvert), &(obj->ntri));
printf("\n%d %d", obj->nvert, obj->ntri);

obj->vert= malloc(obj->nvert * sizeof(vertex));

obj->tri = malloc(obj->ntri * sizeof(triangle));

for(i=0;i<obj->nvert;i++)
{
fscanf(fp, "%f %f %f",&(obj->vert[i].v.x), &(obj->vert[i].v.y), &(obj-
>>vert[i].v.z));
printf("%f %f %f", obj->vert[i].v.x, obj->vert[i].v.y, obj-
>>vert[i].v.z);
}

for(i=0;i<obj->ntri;i++)
{
fscanf(fp, "%d %d %d",&(obj->tri[i].v0), &(obj->tri[i].v1), &(obj-
>>tri[i].v2));
printf("%d %d %d", obj->tri[i].v0, obj->tri[i].v1, obj->tri[i].v2);
}

}
return 1;
}

int main()
{

object *obj;
char *s;
clrscr();
This is not a portable function. The next compiler you compile it on
might not have such a function.
obj = malloc(sizeof(object));
strcpy(s, "sphere.dat");
You have not allocates space for copying.
if(!(read_dat_file(s , obj)))
Anything other than zero is regarded as "true" in C. Therefore the -1
that you return from read_dat_file will also be regarded as true. The
following printf statement will execute only when read_dat_file returns
zero, which it never does.
printf("unsuccessful");
return 0;

}
Mar 9 '08 #5
This is not a portable function. The next compiler you compile it on
might not have such a function.
are you talking about clrscr() ? Ok I will remove it then.
You have not allocates space for copying.
Will this work in your opinion -

char *s = "sphere.dat";

or

char s[] = "sphere.dat";

But other wise what is wrong in using strcpy ?
>
if(!(read_dat_file(s , obj)))

Anything other than zero is regarded as "true" in C. Therefore the -1
that you return from read_dat_file will also be regarded as true. The
following printf statement will execute only when read_dat_file returns
zero, which it never does.
printf("unsuccessful");
return 0;
}
So I guess I should return 0 in read_dat_file function in case the
file cannot be read and 1 if the operation is successful.

Mar 9 '08 #6
i corrected the things santosh said and now the program is giving
"unsuccessful" as o/p. I do not understand what is the problem in
reading the file and printing it.
Mar 9 '08 #7
Cell wrote:
>
>This is not a portable function. The next compiler you compile it on
might not have such a function.

are you talking about clrscr() ? Ok I will remove it then.
>You have not allocates space for copying.

Will this work in your opinion -

char *s = "sphere.dat";

or

char s[] = "sphere.dat";
Yes, both will.
But other wise what is wrong in using strcpy ?
Nothing. But in the statement:

strcpy(s, "sphere.dat");

the string pointed to by the second argument is copied to the address
given as the first argument. But 's' has not been previously
initialised to point to some valid storage, so the strcpy call will
write to some random address, which could lead to anything from silent
memory corruption to a system crash.

You can initialise 's' like this:

s = malloc(strlen("sphere.dat") + 1);
if(!(read_dat_file(s , obj)))

Anything other than zero is regarded as "true" in C. Therefore the -1
that you return from read_dat_file will also be regarded as true. The
following printf statement will execute only when read_dat_file
returns zero, which it never does.
printf("unsuccessful");
return 0;
}

So I guess I should return 0 in read_dat_file function in case the
file cannot be read and 1 if the operation is successful.
That's one possibility. All that C knows about is that zero is false, a
non-zero value is true.

Mar 9 '08 #8
Cell wrote:
i corrected the things santosh said and now the program is giving
"unsuccessful" as o/p. I do not understand what is the problem in
reading the file and printing it.
Here is my version of your code. Please try with your file.

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

typedef struct vectorstruct {
double x, y, z;
} vector;

typedef struct verticesstruct {
vector v;
} vertex;

typedef struct trianglestruct {
int v0, v1, v2;
} triangle;

typedef struct objectstruct {
int nvert;
int ntri;
vertex *vert;
triangle *tri;
} object;

int read_dat_file(FILE *fp, object obj)
{
int rc = 1, i;
char *mfail_msg = "malloc() failed. line: %d\n";
char *fscfail_msg = "fscanf() failed. line: %d\n";

while (1) {
if (fscanf(fp, "%d %d", &(obj.nvert), &(obj.ntri)) != 2) {
fprintf(stderr, fscfail_msg, __LINE__);
rc = 0;
break;
}
printf("%d %d\n", obj.nvert, obj.ntri);

obj.vert = malloc(obj.nvert * sizeof *(obj.vert));
obj.tri = malloc(obj.ntri * sizeof *(obj.tri));
if (!obj.vert || !obj.tri) {
fprintf(stderr, mfail_msg, __LINE__);
rc = 0;
break;
}

for (i = 0; i < obj.nvert; i++) {
if (fscanf(fp, "%lf %lf %lf", &((obj.vert[i]).v.x),
&((obj.vert[i]).v.y), &((obj.vert[i]).v.z)) != 3) {
fprintf(stderr, fscfail_msg, __LINE__);
rc = 0;
break;
}
printf("%f %f %f\n", (obj.vert[i]).v.x, (obj.vert[i]).v.y,
(obj.vert[i]).v.z);
}

for (i = 0; i < obj.ntri; i++) {
if (fscanf(fp, "%d %d %d", &((obj.tri[i]).v0),
&((obj.tri[i]).v1),
&((obj.tri[i]).v2)) != 3) {
fprintf(stderr, fscfail_msg, __LINE__);
rc = 0;
break;
}
printf("%d %d %d\n", (obj.tri[i]).v0, (obj.tri[i]).v1,
(obj.tri[i]).v2);
}
}
if (feof(fp)) return !rc;
else return rc;
}

int main(void)
{
int rc;
object obj;
FILE *fp = fopen("sphere.dat", "r");

if (!fp) { puts("Failed to open file."); return EXIT_FAILURE; }
rc = read_dat_file(fp, obj);
if (rc == 0) {
puts("read_dat_file() failed.");
}
else {
puts("read_dat_file() done.");
}

return !rc;
}

Here for an example file containing:

3 3
1.1 2.1 3.1
4.1 5.1 6.1
7.1 8.1 9.1
0 1 2
0 1 2
0 1 2

The output of the program is:

3 3
1.100000 2.100000 3.100000
4.100000 5.100000 6.100000
7.100000 8.100000 9.100000
0 1 2
0 1 2
0 1 2
fscanf() failed. line: 31
read_dat_file() done.

Mar 9 '08 #9
Cell wrote:
i corrected the things santosh said and now the program is giving
"unsuccessful" as o/p. I do not understand what is the problem in
reading the file and printing it.
As Eric Sosman mentioned, if you want your program to be robust you need
to rethink the way you parse your data file. A corruption in this file
(regardless of whether it is accidental or deliberate) will likely
choke fscanf and either cause it to fail (which is the better option)
or make it return wrong values (which is worse.)

One alternative is to use fgets to read in a complete line from the file
and convert the appropriate elements of that line with the strto*
family of functions. strtol is for long (can also be used for int,
short and signed char), strtoul is for unsigned long (also for unsigned
int, unsigned short, and unsigned char), strtoull is for unsigned long
long, strtoll is for long long, strtod is for double, strtof is for
float, strtold is for long double. There are others too like strtoimax
and strtoumax for intmax_t and uintmax_t.

The strto* functions return more information about what exactly went
wrong with the conversion, point you to the place where the conversion
failed, and do not exhibit undefined behaviour on overflow or
underflow.

You'll still need to check the converted values for semantic validity of
course.

For reference of all the useful functions of the Standard C library see:

<http://www.dinkumware.com/manuals/>

Mar 9 '08 #10
Cell wrote:
>
i corrected the things santosh said and now the program is giving
"unsuccessful" as o/p. I do not understand what is the problem in
reading the file and printing it.
Nor do I. I quoted your entire post above, and I can see nothing
objectionable in it, apart from the lower case i. However, it
won't compile.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Mar 10 '08 #11
On Sun, 9 Mar 2008 08:51:03 -0700 (PDT), Cell <at********@gmail.com>
wrote:
>i corrected the things santosh said and now the program is giving
"unsuccessful" as o/p. I do not understand what is the problem in
reading the file and printing it.
You may think you did but until you show us the updated code we will
not be able to help.
Remove del for email
Mar 11 '08 #12
On Mar 9, 9:47 pm, santosh <santosh....@gmail.comwrote:
Cell wrote:
i corrected the things santosh said and now the program is giving
"unsuccessful" as o/p. I do not understand what is the problem in
reading the file and printing it.

Here is my version of your code. Please try with your file.

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

typedef struct vectorstruct {
double x, y, z;

} vector;

typedef struct verticesstruct {
vector v;

} vertex;

typedef struct trianglestruct {
int v0, v1, v2;

} triangle;

typedef struct objectstruct {
int nvert;
int ntri;
vertex *vert;
triangle *tri;

} object;

int read_dat_file(FILE *fp, object obj)
{
int rc = 1, i;
char *mfail_msg = "malloc() failed. line: %d\n";
char *fscfail_msg = "fscanf() failed. line: %d\n";

while (1) {
if (fscanf(fp, "%d %d", &(obj.nvert), &(obj.ntri)) != 2) {
fprintf(stderr, fscfail_msg, __LINE__);
rc = 0;
break;
}
printf("%d %d\n", obj.nvert, obj.ntri);

obj.vert = malloc(obj.nvert * sizeof *(obj.vert));
obj.tri = malloc(obj.ntri * sizeof *(obj.tri));
if (!obj.vert || !obj.tri) {
fprintf(stderr, mfail_msg, __LINE__);
rc = 0;
break;
}

for (i = 0; i < obj.nvert; i++) {
if (fscanf(fp, "%lf %lf %lf", &((obj.vert[i]).v.x),
&((obj.vert[i]).v.y), &((obj.vert[i]).v.z)) != 3) {
fprintf(stderr, fscfail_msg, __LINE__);
rc = 0;
break;
}
printf("%f %f %f\n", (obj.vert[i]).v.x, (obj.vert[i]).v.y,
(obj.vert[i]).v.z);
}

for (i = 0; i < obj.ntri; i++) {
if (fscanf(fp, "%d %d %d", &((obj.tri[i]).v0),
&((obj.tri[i]).v1),
&((obj.tri[i]).v2)) != 3) {
fprintf(stderr, fscfail_msg, __LINE__);
rc = 0;
break;
}
printf("%d %d %d\n", (obj.tri[i]).v0, (obj.tri[i]).v1,
(obj.tri[i]).v2);
}
}
if (feof(fp)) return !rc;
else return rc;

}

int main(void)
{
int rc;
object obj;
FILE *fp = fopen("sphere.dat", "r");

if (!fp) { puts("Failed to open file."); return EXIT_FAILURE; }
rc = read_dat_file(fp, obj);
if (rc == 0) {
puts("read_dat_file() failed.");
}
else {
puts("read_dat_file() done.");
}

return !rc;

}

Here for an example file containing:

3 3
1.1 2.1 3.1
4.1 5.1 6.1
7.1 8.1 9.1
0 1 2
0 1 2
0 1 2

The output of the program is:

3 3
1.100000 2.100000 3.100000
4.100000 5.100000 6.100000
7.100000 8.100000 9.100000
0 1 2
0 1 2
0 1 2
fscanf() failed. line: 31
read_dat_file() done.

Can you please explain why the fscanf is showing error at line 31 ?

Im getting similar messages for random line numbers.
Mar 11 '08 #13
Cell wrote:
On Mar 9, 9:47 pm, santosh <santosh....@gmail.comwrote:
>Cell wrote:
i corrected the things santosh said and now the program is giving
"unsuccessful" as o/p. I do not understand what is the problem in
reading the file and printing it.

Here is my version of your code. Please try with your file.
<snip code>
>The output of the program is:

3 3
1.100000 2.100000 3.100000
4.100000 5.100000 6.100000
7.100000 8.100000 9.100000
0 1 2
0 1 2
0 1 2
fscanf() failed. line: 31
read_dat_file() done.


Can you please explain why the fscanf is showing error at line 31 ?
It is because of attempting to read at end-of-file. It has, as you can
see from the file contents I showed you and the output, read all the
values in the file, and thus the next call during the loop fails due to
the file having reached end-of-file. If fscanf had failed due to
reasons other than end-of-file, the output "read_dat_file() failed."
would have been printed instead.
Im getting similar messages for random line numbers.
This probably means that the exact format of your file is not what the
various fscanf calls are expecting it to be.

Unless you post a complete, compilable version of your program that
exhibits the errors along with the complete (or a representative)
contents of your data file, it hard to say what exactly might be wrong
with your code.

The *scanf functions are, as I said before, rather difficult to use in a
robust manner. You might try my advice of using fgets with
strtol/strtoul/strtod.

Mar 11 '08 #14

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

Similar topics

8
by: michi | last post by:
Hello everybody, I have following problem: I have an array of pointers to structures: table* tab = new table; and structure table is like this: struct table{ CSLL::node* chain;
4
by: emma middlebrook | last post by:
Hi Straight to the point - I don't understand why System.Array derives from IList (given the methods/properties actually on IList). When designing an interface you specify a contract. Deriving...
8
by: ulyses | last post by:
I'm trying to put pointer to flexible array of structures in other structure. I want to have pointer to array of pixels in screen structure. Here is mine code, but I think it isn't quite all right:...
104
by: Leszek | last post by:
Hi. Is it possible in javascript to operate on an array without knowing how mamy elements it has? What i want to do is sending an array to a script, and this script should add all values from...
7
by: Sam | last post by:
Hello I have a structure called Company. struct Company { char *employee; char *employee_address; }; I want to build an array of this structure but the number of employees will change...
12
by: gcary | last post by:
I am having trouble figuring out how to declare a pointer to an array of structures and initializing the pointer with a value. I've looked at older posts in this group, and tried a solution that...
11
by: skumar434 | last post by:
Hi everybody, I am faceing problem while assigning the memory dynamically to a array of structures . Suppose I have a structure typedef struct hom_id{ int32_t nod_de; int32_t hom_id;
44
by: svata | last post by:
Hello, I wonder how to resize such array of structures using realloc()? #include <stdio.h> #include <stdlib.h> #define FIRST 7 typedef struct { char *name;
17
by: Ben Bacarisse | last post by:
candide <toto@free.frwrites: These two statements are very different. The first one is just wrong and I am pretty sure you did not mean to suggest that. There is no object in C that is the...
5
by: =?Utf-8?B?QXlrdXQgRXJnaW4=?= | last post by:
Hi Willy, Thank you very much for your work. C++ code doesnot make any serialization. So at runtime C# code gives an serialization error at "msg_file_s sa = (msg_file_s) bf.Deserialize(ms);"...
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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
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...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.