2D array of structures

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

    #16
    Re: 2D array of structures

    svata:
    Hello Frederick,

    Hello svata :)

    I know it doesn't make sense. I was wrong in my assumption.
    I should use p_structure = (STRUCTURE **) malloc(FIRST *
    sizeof(STRUCTUR E*));
    >
    but anyway... should rather use array of structures.
    >
    >
    typedef structure {
    code goes here...
    } _structure;
    >
    _structure *p_structure;

    One thing that you'll notice as you program more and more is that you'll
    come to use abbreviations (most programmers do in anyway). Humans love
    shortcuts. "should have" became "should've" , which became "shuda". The
    words "until" and "because" are slowly but surely becoming "til" and
    "cause".

    When I myself define a pointer variable, I simply prefix "p" to the name; I
    used to put an underscore with it too but then more months passed by and I
    got lazier and lazier. The variable name "p_structur e" is a bit of a
    mouthful, maybe you'd prefer to keep the names small.

    There are a few different prevalent coding styles out there. My own style
    works as follows:

    (1) Functions and Types start with a capital letter. If it consists of more
    than one word, than the next word starts with an initial capital, e.g.

    void TruncateLastFiv eDigits(char*);

    (2) Objects start with a lower case letter. If it consists of more than one
    word, then underscores are used, e.g.

    int len_main_str = 34;

    (3) For a pointer, I prefix a simple "p" to the name where possible:

    void (*pFunc)(int) = Func;
    void (**ppFunc)(int) = &pFunc;

    int *pobj = &obj;
    int **ppobj = &pobj;
    int ***pppobj = &ppobj;

    (4) Macro names are in ALL CAPS. No other name should be written in ALL
    CAPS, e.g.:

    #define LEN 5
    #define SQR(x) ((x)*(x))

    Of course, this is just my own style. I'm not trying to shove it down your
    throat, but I'm just suggesting it as I thought you might like it.

    // and then malloc()
    >
    p_structure = malloc( INT * sizeof(_structu re));
    >
    if am I right?

    Yes, you're right. It's handy though to not have to repeat the name of the
    type:

    int *const p = malloc(5 * sizeof(int));

    can be written as:

    int *const p = malloc(5 * sizeof*p);

    Now, if we change the type to double, we only have to change "p":

    double *const p = malloc(5 * sizeof*p);

    Here's a taste of how I might write the code:

    #include <stddef.h /* To use "size_t" */
    #include <stdlib.h /* To use "malloc" and "free" */

    typedef struct MyStruct {
    int i;
    } MyStruct;

    size_t GetNumberFromSo mewhere(void); /* Defined elsewhere */

    int main(void)
    {
    size_t const len = GetNumberFromSo mewhere();

    MyStruct *const p = malloc(len * sizeof*p);

    /* ... */

    free(p);

    return 0;
    }

    --

    Frederick Gotham

    Comment

    • Flash Gordon

      #17
      Re: 2D array of structures

      svata wrote:

      Please do not top post. Your reply belongs under the text you are
      replying to, not above.
      svata
      >I agree with what you've said, but the OP should also read section 6 of
      >the comp.lang.c FAQ before posting back here. Section 6 includes ways of
      >dynamically allocating space for things that work like 2D arrays. The
      >FAQ can be found at http://c-faq.com/
      I always use google to search an answer, but often results are not
      relevant.
      I did not suggest using Google, I suggested a specific resource and a
      particular area in it. From another post here it is obvious you have not
      followed that advice, and if you don't bother following advice or
      posting properly I see no reason to bother giving you advice.
      --
      Flash Gordon

      Comment

      • Keith Thompson

        #18
        Re: 2D array of structures

        Chris Dollin <chris.dollin@h p.comwrites:
        [...]
        If you /must/ use a typedef for a structure -- you don't
        need to, and some wise people argue that you shouldn't
        (although others argue that those arguments aren't
        convincing) -- you should also give it a /sensible/
        name. "structure" isn't.
        >
        typedef struct yourStructTagHe re
        {
        int x;
        int y;
        } Point;
        There's also no need to use different identifiers for the struct tag
        and the typedef name:

        typedef struct Point {
        int x;
        int y;
        } Point;

        Now you can refer to the type either as "Point" or as "struct Point".

        The purpose of the typedef is to allow you to use a single identifer
        to refer to the type. The argument Chris alluded to above *against*
        using a typedef is that gives a second name to a type that already has
        a perfectly good name. For example, I would have declared it as:

        struct Point {
        int x;
        int y;
        };

        and just refer to the type as "struct Point".

        But plenty of smart people prefer to use the typedef. And if your
        structure doesn't contain any pointers to itself (as for a linked list
        node, for example), you don't need the struct tag:

        typedef struct {
        int x;
        int y;
        } Point;

        The drawback of this is that the name "Point" doesn't become visible
        until the end of the declaration, so you can't declare a member of
        type Point*.

        --
        Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
        San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
        We must do something. This is something. Therefore, we must do this.

        Comment

        • CBFalconer

          #19
          Re: 2D array of structures

          Frederick Gotham wrote:
          >
          .... snip ...
          >
          One thing that you'll notice as you program more and more is that
          you'll come to use abbreviations (most programmers do in anyway).
          Humans love shortcuts. "should have" became "should've" , which
          became "shuda". The words "until" and "because" are slowly but
          surely becoming "til" and "cause".
          Not the smarter ones. They try to stick to English, and remain
          fairly clear to their readers. Should've is legitimate English,
          shuda is an execresence. Misuse of the word 'cause' causes nothing
          but confusion.

          --
          Chuck F (cbfalconer at maineline dot net)
          Available for consulting/temporary embedded and systems.
          <http://cbfalconer.home .att.net>

          Comment

          • Richard Heathfield

            #20
            Re: 2D array of structures

            Keith Thompson said:
            Chris Dollin <chris.dollin@h p.comwrites:
            [...]
            >If you /must/ use a typedef for a structure -- you don't
            >need to, and some wise people argue that you shouldn't
            >(although others argue that those arguments aren't
            >convincing) -- you should also give it a /sensible/
            >name. "structure" isn't.
            >>
            > typedef struct yourStructTagHe re
            > {
            > int x;
            > int y;
            > } Point;
            >
            There's also no need to use different identifiers for the struct tag
            and the typedef name:
            >
            typedef struct Point {
            int x;
            int y;
            } Point;
            It's true that there's no C reason to use different identifiers, but I do so
            anyway because it helps Microsoft's "Intellisen se" to work out what you
            mean when you hit the button that says "take me to your definition". Not
            that I use Microsoft C terribly often - but when I do, I usually end up
            thanking myself for using a unique tag name. My preferred style nowadays
            is:

            struct foo_
            {
            char coal;
            short wait;
            unsigned letter;
            long time;
            float away;
            double trouble;
            bar baz;
            ad nauseam;
            };

            typedef struct foo_ foo;

            <snip>

            --
            Richard Heathfield
            "Usenet is a strange place" - dmr 29/7/1999

            email: normal service will be restored as soon as possible. Please do not
            adjust your email clients.

            Comment

            • Keith Thompson

              #21
              Re: 2D array of structures

              Richard Heathfield <invalid@invali d.invalidwrites :
              Keith Thompson said:
              [...]
              >There's also no need to use different identifiers for the struct tag
              >and the typedef name:
              >>
              > typedef struct Point {
              > int x;
              > int y;
              > } Point;
              >
              It's true that there's no C reason to use different identifiers, but I do so
              anyway because it helps Microsoft's "Intellisen se" to work out what you
              mean when you hit the button that says "take me to your definition". Not
              that I use Microsoft C terribly often - but when I do, I usually end up
              thanking myself for using a unique tag name.
              [...]

              Alas, it's sometimes necessary to obfuscate your code to cater to
              inferior tools.

              --
              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
              San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
              We must do something. This is something. Therefore, we must do this.

              Comment

              • Richard Heathfield

                #22
                Re: 2D array of structures

                Keith Thompson said:
                Alas, it's sometimes necessary to obfuscate your code to cater to
                inferior tools.
                I am not convinced that a mere trailing underscore on a tag name constitutes
                obfuscation.

                --
                Richard Heathfield
                "Usenet is a strange place" - dmr 29/7/1999

                email: normal service will be restored as soon as possible. Please do not
                adjust your email clients.

                Comment

                • svata

                  #23
                  Re: 2D array of structures

                  Hello,

                  I meant that I admire people who knows more than I do :) But, I try to
                  code first, and if I'm stuck I ask for help. I don't expect someone to
                  do coding for me.
                  But anyway, thanks for your patience.

                  svata

                  Richard Heathfield wrote:
                  That's fine sometimes, but there are also times when it's best to learn from
                  other people's knowledge and experience. If you learn C "by doing", you're
                  likely to end up doing lots of things that aren't correct, but which happen
                  to behave in a particular way on your current system. Switch systems, and
                  all your code breaks. Oops.
                  >
                  Chris is an expert on C. Listen to Chris.
                  >
                  --
                  Richard Heathfield
                  "Usenet is a strange place" - dmr 29/7/1999

                  email: normal service will be restored as soon as possible. Please do not
                  adjust your email clients.

                  Comment

                  • svata

                    #24
                    Re: 2D array of structures

                    I'm sorry for that mess.
                    (svata's quoting was misleading anyway, since he half-top-posted.)
                    >
                    So, I have to ask. I did my best, my code is almost finished, but I'm
                    looking for someone who can do code review and comment it. Via email
                    preferably.
                    There are some bugs, which I can't get rid of. I use both Borland C
                    compiler and gcc.
                    On windows it runs with some drawbacks, on linux it crashes due to bad
                    use of realloc().

                    So, is anyone ready for code review please?
                    Chris is an expert on C.
                    >
                    I'd hesitate to describe myself so, since there's so much C I don't
                    know (most of the C99 stuff, for example!) and I've used it in so
                    few environments. I know /some/ stuff about C. I hope it's useful
                    stuff.
                    >
                    Listen to Chris.
                    >
                    Is your singing so bad? :)
                    But not when I'm singing.
                    >
                    --
                    svata

                    Comment

                    • Richard Heathfield

                      #25
                      Re: 2D array of structures

                      svata said:
                      I did my best, my code is almost finished, but I'm
                      looking for someone who can do code review and comment it.
                      Try posting it, then.
                      Via email preferably.
                      Good luck with that, but in general you'll find that the email responders
                      are those who fear their answers will not survive in the glare of public
                      scrutiny.

                      --
                      Richard Heathfield
                      "Usenet is a strange place" - dmr 29/7/1999

                      email: normal service will be restored as soon as possible. Please do not
                      adjust your email clients.

                      Comment

                      • Chris Dollin

                        #26
                        Re: 2D array of structures

                        Richard Heathfield wrote:
                        Chris Dollin said:
                        >
                        >Richard Heathfield wrote:
                        >
                        >>Chris is an expert on C.
                        >>
                        >I'd hesitate to describe myself so,
                        >
                        Think "relative". Compared to most OPs around here, you're a towering
                        genius!
                        You've met me. You know "towering" isn't in my job description.

                        --
                        Chris "nor is the G-word ..." Dollin
                        "People are part of the design. It's dangerous to forget that." /Star Cops/

                        Comment

                        • svata

                          #27
                          Re: 2D array of structures

                          Richard Heathfield wrote:

                          The only problem is that the code is supposed as a school task. I do
                          not fear to reveal my code at all. But would like to avoid my lecturer
                          to find my code before I submit it.
                          Good luck with that, but in general you'll find that the email responders
                          are those who fear their answers will not survive in the glare of public
                          scrutiny.
                          >
                          --
                          Richard Heathfield
                          "Usenet is a strange place" - dmr 29/7/1999

                          email: normal service will be restored as soon as possible. Please do not
                          adjust your email clients.

                          Comment

                          • Jens Thoms Toerring

                            #28
                            Re: 2D array of structures

                            Please don't top-post. I have rearranged your post to have what
                            you were replying to to come first:

                            svata <svatoboj@centr um.czwrote:
                            Richard Heathfield wrote:
                            Good luck with that, but in general you'll find that the email responders
                            are those who fear their answers will not survive in the glare of public
                            scrutiny.
                            The only problem is that the code is supposed as a school task. I do
                            not fear to reveal my code at all. But would like to avoid my lecturer
                            to find my code before I submit it.
                            First question: why can't you ask you lecturer? Isn't (s)he supposed
                            to teach you? Or are you supposed to have understood already every-
                            thing and this is a test if you did?

                            Next question: are you not allowed to ask others for help? If you're
                            allowed what's the problem with posting your code here? If you're not
                            allowed why should we help you cheating? But if you have some other
                            reason for not posting your code try to write a similar program and,
                            if it exhibits the same bugs, post that here and apply what you learned
                            from the replies to the program you have to hand in. As a bonus you may
                            even figure out yourself what the error is when you try to write a
                            similar program...
                            Regards, Jens
                            --
                            \ Jens Thoms Toerring ___ jt@toerring.de
                            \______________ ____________ http://toerring.de

                            Comment

                            • svata

                              #29
                              Re: 2D array of structures

                              Jens Thoms Toerring wrote:
                              Please don't top-post. I have rearranged your post to have what
                              you were replying to to come first:
                              Ok, I remember it from now on :)
                              >
                              First question: why can't you ask you lecturer? Isn't (s)he supposed
                              to teach you? Or are you supposed to have understood already every-
                              thing and this is a test if you did?
                              I can, but I'm somehow supposed do my own research.
                              >
                              Next question: are you not allowed to ask others for help? If you're
                              allowed what's the problem with posting your code here? If you're not
                              allowed why should we help you cheating? But if you have some other
                              reason for not posting your code try to write a similar program and,
                              if it exhibits the same bugs, post that here and apply what you learned
                              from the replies to the program you have to hand in. As a bonus you may
                              even figure out yourself what the error is when you try to write a
                              similar program...
                              I don't ask anyone her to help me to cheat. I can ask for help another
                              people, of course.
                              I rather wonder if someone can comment it to help me to learn good
                              programming habits.

                              So my code follows:

                              #include <stdio.h>
                              #include <string.h>
                              #include <stdlib.h>
                              #define FIRST 7
                              #define MAX 10

                              // First of variables have to be declared
                              char answer;
                              char item_name[MAX];
                              char *p_item_name;
                              char string;
                              int i;
                              int j;
                              int str_len;
                              float amount;
                              int NEW_SIZE;


                              typedef struct {
                              // to store strig entered by user
                              char *name;
                              // to be able determine whether it is predefined menu or not, used
                              when receipt is printed out
                              int menu;
                              // to be able determine to which menu group
                              int group;
                              // to store price entered by user
                              float price;
                              // important as we need to see which index is already used
                              int used;
                              } SHOPPING;

                              SHOPPING *p_shopping;

                              // Declaring of menu items, necessary for later reuse in array
                              char *p_menu_items[] = {"Bread", "Butter", "Confectionary" , "Fruit",
                              "Meat", "Milk", "Vegetables ", "Other"};

                              // Declaring choices menu, not being used in any other array
                              char *p_menu_choices[] = {"Sub-total", "Total", "Quit"};


                              int main() {

                              int store_data(int) ; // declaring we want to use function
                              // now, allocating memory for first 8 arrays, menu is going to be
                              stored there
                              p_shopping = malloc(FIRST * sizeof *p_shopping);
                              if ( p_shopping == NULL ) {
                              printf("Failed to allocate memory, exiting...");
                              return 1;
                              }

                              while (1) { // infinitive loop
                              // This cannot be part of a menu array, to be printed once only!!
                              printf("\nEnter your choice: \n");
                              // Putting menu together by looping through 2 arrays
                              for ( i = 0; i < (FIRST + 1); i++ ) {
                              // it's time to allocate memory on the fly, as we have
                              different string size
                              p_shopping[i].name = malloc((strlen( p_menu_items[i]) + 1) *
                              sizeof(char));
                              if ( p_shopping[i].name == NULL ) {
                              printf("Failed to allocate memory, exiting...");
                              return 1;
                              }
                              //copying content of menu items to shopping structure for later use
                              strcpy(p_shoppi ng[i].name, p_menu_items[i])
                              // and set int used to 1, to determine which indexes are used
                              p_shopping[i].used = 1;
                              printf("\t\t\t %d. %s\n", (i + 1), p_shopping[i].name );
                              // as this is predefined menu, we have to state it here, for future
                              use
                              p_shopping[i].menu = 1;
                              // set int group to its value according group of items, for future
                              use
                              p_shopping[i].group = i;
                              }
                              // second array for menu
                              for ( i = 0; i < 3; i++ ) {
                              // Neccessary to align, because there are numbers greater than 9 :)
                              if ( i < 1 ) {
                              printf("\t\t\t %d. %s\n", ( i + 9 ), p_menu_choices[i]);
                              }
                              else {
                              printf("\t\t\t% d. %s\n", ( i + 9 ), p_menu_choices[i]);
                              }
                              }
                              // This cannot be a part of menu array, to be printed once only!!
                              printf("\t\t\t= ====");
                              scanf("%d", &choice);
                              getchar();


                              switch(choice) {
                              // Optional exit, user has to confirm it...
                              case 0 :
                              while (1) {
                              printf("Do you really want to exit? [y/n]: ");
                              getchar();
                              scanf("%c", &answer);
                              getchar();

                              switch (answer) {
                              case 'y':
                              printf("Ok, as you wish, quiting...\n");
                              return 0;

                              case 'n':
                              printf("Ok, returning back...\n");
                              // had to use go to, otherwise it is almost impossible to escape
                              infinite loop
                              goto exit;

                              default:
                              printf("Please answer 'y' or 'n'!\n");
                              break;
                              }
                              }

                              case 1 :
                              store_data(0);
                              break;

                              case 2 :
                              store_data(1);
                              break;

                              case 3 :
                              store_data(2);
                              break;

                              case 4 :
                              store_data(3);
                              break;

                              case 5 :
                              store_data(4);
                              break;

                              case 6 :
                              store_data(5);
                              break;

                              case 7 :
                              store_data(6);
                              break;

                              case 8 :
                              store_data(7);
                              break;

                              case 9 :
                              store_data(-1);
                              break;

                              case 10 :
                              store_data(-1);
                              printf("Enter amount tendered: ");
                              scanf("%f", &amount);
                              // to test whether amount tendered is greater than total sum
                              if ( amount < sub_sum ) {
                              printf("Tendere d amount is lower than total sum!!!");
                              // if so, exit here and user has to enter new choice
                              break;
                              }
                              else {
                              printf("Your change is %4.2f\n\n", (amount - sub_sum));
                              }

                              case 11 :
                              // user wants to leave
                              printf("Thank you for shopping\n");
                              return 1;

                              default :
                              // user entered invalid choice
                              printf("Invalid choice entered, quiting....\n") ;
                              return 0;
                              }
                              // here points goto from switch 0
                              exit:
                              // we do nothing here, just leaving inner loop
                              ;
                              }
                              }

                              int store_data(int group) {
                              int choice;
                              float sum;
                              float sub_sum;
                              static int SIZE = 0; // need to use persistent variable, which counts
                              invocation of function
                              if ( group == -1 ) {
                              // this is really important, otherwise it screws up the result :)
                              sub_sum = 0;
                              // now, receipt is expected to be printed
                              printf("####### ############### ###\n#\t YOUR
                              RECEIPT\t#\n### ############### #######\n\n");
                              // as we have 8 main menu items, we want to print them, one by one
                              for ( j = 0; j < (FIRST + 1); j++ ) { // can use FIRST as we know
                              that first 8 items are menus...
                              printf("%s\n-------------------------------\n", p_shopping[j].name);
                              for ( i = 0; i < (NEW_SIZE + 1); i++ ) { // and now print relevant
                              submenu
                              if ( p_shopping[i].group == j && p_shopping[i].menu != 1 ) {
                              sub_sum += p_shopping[i].price;
                              printf("%s\t\t\ t%4.2f\n", p_shopping[i].name,
                              p_shopping[i].price);
                              }
                              }
                              // submenu separator :)
                              printf("\n");
                              }
                              printf("------------------------------\n");
                              printf("Total\t \t\t%4.2f\n\n", sub_sum);
                              return 0;
                              }
                              else {
                              SIZE ++; // we want keep trace how many times is this part invoked
                              NEW_SIZE = SIZE + FIRST;
                              for ( i = 0; i < (NEW_SIZE); i++ ) {
                              printf("%d\t%d. %d %s\n", i, p_shopping[i].used, p_shopping[i].group,
                              p_shopping[i].name );
                              }
                              printf("Enter description (max. size %d): ", sizeof(item_nam e));
                              if (fgets(item_nam e, sizeof(item_nam e), stdin) != NULL){
                              if (( p_item_name = strchr(item_nam e, '\n')) != NULL )
                              *p_item_name = '\0';
                              }
                              p_shopping[NEW_SIZE].used = 0; // must be set to 0 as it can have
                              random value
                              printf("Price: ");
                              scanf("%f", &sum);
                              // it's time to resize array now, as we have data we need
                              p_shopping = realloc(p_shopp ing, (sizeof(*p_shop ping) * (NEW_SIZE +
                              1)));
                              if ( p_shopping == NULL ) {
                              printf("Failed to allocate memory, exiting...");
                              return 1;
                              }
                              else {
                              for ( i = 0; i < (NEW_SIZE + 1); i++ ) {
                              if ( i == (NEW_SIZE)) {
                              p_shopping[i].name = malloc((strlen( item_name) + 1) *
                              sizeof(char));
                              strcpy(p_shoppi ng[i].name, item_name);
                              p_shopping[i].used = 1;
                              p_shopping[i].price = sum;
                              p_shopping[i].group = group;
                              }
                              //printf("%d\t%d. %d %s\n", i, p_shopping[i].used,
                              p_shopping[i].group, p_shopping[i].name );
                              }
                              }
                              return 0;
                              }
                              }

                              This example has cca 250 lines, I hope it is appropriate to post here.
                              There is a bug in use of realloc() and so far I was unable to figure it
                              out. I did a lot of "debuging" by using many printf() commands at
                              different stages.
                              So please feel free to comment coding style, semantic etc. I know, this
                              is not the best solution, but this my attempt to find it. I'm supposed
                              to learn by doing.

                              Svata

                              Comment

                              • CBFalconer

                                #30
                                Re: 2D array of structures

                                svata wrote:
                                Richard Heathfield wrote:
                                >
                                The only problem is that the code is supposed as a school task. I
                                do not fear to reveal my code at all. But would like to avoid my
                                lecturer to find my code before I submit it.
                                >
                                >Good luck with that, but in general you'll find that the email
                                >responders are those who fear their answers will not survive in
                                >the glare of public scrutiny.
                                You have been asked multiple times to stop top-posting, yet you
                                insist on so doing. I conclude you really do not care whether or
                                not anyone reads your posts. I shall not be doing so.

                                --
                                Chuck F (cbfalconer at maineline dot net)
                                Available for consulting/temporary embedded and systems.
                                <http://cbfalconer.home .att.net>


                                Comment

                                Working...