array of structures.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Cell

    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);


  • Harald van =?UTF-8?b?RMSzaw==?=

    #2
    Re: array of structures.

    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. :)

    Comment

    • Cell

      #3
      Re: array of structures.

      #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(o bject));
      strcpy(s, "sphere.dat ");
      if(!(read_dat_f ile(s , obj)))
      printf("unsucce ssful");
      return 0;

      }




      Comment

      • Cell

        #4
        Re: array of structures.

        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.

        Comment

        • santosh

          #5
          Re: array of structures.

          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(o bject));
          strcpy(s, "sphere.dat ");
          You have not allocates space for copying.
          if(!(read_dat_f ile(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("unsucce ssful");
          return 0;
          >
          }

          Comment

          • Cell

            #6
            Re: array of structures.

            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_f ile(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("unsucce ssful");
            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.

            Comment

            • Cell

              #7
              Re: array of structures.

              i corrected the things santosh said and now the program is giving
              "unsuccessf ul" as o/p. I do not understand what is the problem in
              reading the file and printing it.

              Comment

              • santosh

                #8
                Re: array of structures.

                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_f ile(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("unsucce ssful");
                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.

                Comment

                • santosh

                  #9
                  Re: array of structures.

                  Cell wrote:
                  i corrected the things santosh said and now the program is giving
                  "unsuccessf ul" 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(F ILE *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.nver t * 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.d at", "r");

                  if (!fp) { puts("Failed to open file."); return EXIT_FAILURE; }
                  rc = read_dat_file(f p, 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.

                  Comment

                  • santosh

                    #10
                    Re: array of structures.

                    Cell wrote:
                    i corrected the things santosh said and now the program is giving
                    "unsuccessf ul" 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/>

                    Comment

                    • CBFalconer

                      #11
                      Re: array of structures.

                      Cell wrote:
                      >
                      i corrected the things santosh said and now the program is giving
                      "unsuccessf ul" 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

                      Comment

                      • Barry Schwarz

                        #12
                        Re: array of structures.

                        On Sun, 9 Mar 2008 08:51:03 -0700 (PDT), Cell <atindrasrs@gma il.com>
                        wrote:
                        >i corrected the things santosh said and now the program is giving
                        >"unsuccessfu l" 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

                        Comment

                        • Cell

                          #13
                          Re: array of structures.

                          On Mar 9, 9:47 pm, santosh <santosh....@gm ail.comwrote:
                          Cell wrote:
                          i corrected the things santosh said and now the program is giving
                          "unsuccessf ul" 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(F ILE *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.nver t * 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.d at", "r");
                          >
                          if (!fp) { puts("Failed to open file."); return EXIT_FAILURE; }
                          rc = read_dat_file(f p, 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.

                          Comment

                          • santosh

                            #14
                            Re: array of structures.

                            Cell wrote:
                            On Mar 9, 9:47 pm, santosh <santosh....@gm ail.comwrote:
                            >Cell wrote:
                            i corrected the things santosh said and now the program is giving
                            "unsuccessf ul" 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.

                            Comment

                            Working...