Thread: Trimming the fat out of my code for an Array

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    10

    Trimming the fat out of my code for an Array

    Hi all,

    The problem I have got is a file which has a set of date like this:

    F 26 5
    F 64 4
    F 29 2
    M 12 3
    M 40 1
    F 38 4

    The first column represtents Male or Female the second Age and the third is a Selection. What I have to do is populate an array so all females under 25 who answered one are added together, all females under 25 who answered two are added together, so on, and so on.

    Now I could do something like this (note, I just have it outputting to the screen until I have sorted my code out):

    Code:
    {
          while (fscanf(rawdat, "%c %d %d &c", &sex, &age, &range, &newline) != EOF)
    
             if (((sex == 'F') && (age < 25) && (range == 1)))
              printf("%c %d %d\n", sex, age, range);
    
             else if (((sex == 'F') && (age < 25) && (range == 2)))
              printf("%c %d %d\n", sex, age, range);
    
             etc......
    
             etc......
    
       }
    Now this is wildly inefficient code, but it would work. What I am thinking of doing is using a switch statement for the range using a preprocessor directive to fill rows of the array then use the sex and age to fill the columns of the array. The problems I have with this is that I'm declaring the two co-ordinants of the array in separate places and I'm not sure how to do this. Am I barking up the wrong tree with this solution? Is there a better way?

    I hope this makes sense as it's been bugging the hell out of me

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    IMHO a linked list of nodes might be better suited for this sort of thing.
    Each node has two members, age and selection and have two separate linked lists - one for females and one for males.

  3. #3
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    Hi itCbitC,

    Thanks for you reply, I had to google "linked list of nodes" as it was beyond the scope of the course work I am using. I couldn't find any decent tutorials on how to go about this. Do you know of any decent tutorials or examples?

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I'd recommend just making a struct with those three members. Then make your array, an array of structs (ez smeazy), and read everything in from the file.

    Now sort the array, according to the keys you need: set.sex, set.selection, set.age.

    I'll bet you don't know how to do multi-key sorts, right? We'll help you. Do the above and see what your Muse might enlighten you with.

    We'll help, too.

    You know how to define a struct, right? You know how to make one instance of the struct, right?

    Nothing wrong with lists, but I wouldn't be messing around with them when there was productive programming to
    be done, unless you already know them.
    Last edited by Adak; 12-08-2008 at 03:05 PM.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    If linked lists have not yet been covered, then take Adak's approach.
    The FAQ has an excellent tutorial on linked lists just in case.
    http://faq.cprogramming.com/cgi-bin/...&id=1073086407

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You might as well learn how to use a linked-list if you don't, they are GREAT for improving your grip on pointers & memory BUT their use-value may be exaggerated and this is such a case, I think.

    Your original solution could be made better by nesting the if's:
    Code:
         
    if (sex== 'F) {
          if (age<25) {
               switch (range) {
                          ...you know...
          else {
               switch (range) {
                            ...I guess we could make a function for this switch...
         }
    else {
         if (age<25) {
               switch (range) {
                          ...you know...
    But linked lists will be much more exiting, and at least then you will have found a practical use for them

    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    I've included all my code so far, I started out setting out my field then when that was looking fine commenting it out. You've lost me Adak, I think I've seen working on this too long without coffee, going to go grab one and see if it starts making sense.

    Code:
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    
    #define SIZE 8 // Max. buffer size
    #define RANGE 6; // Max range size for array
    
    void bar(int number);
    void space(int number);
    
    void main()
    {
       FILE *rawdat;
       //char buffer[SIZE];
       int rangearray[6][6];
       char sex, newline;
       int  age, range;
       //int rangenum[RANGE];
    
    
       rawdat = fopen("H:\\sp3work\\custsurvey.dat","r");
       if (rawdat == NULL)
       {
          printf("Cannot locate file");
       }
       else
       {
          while (fscanf(rawdat, "&#37;c %d %d &c", &sex, &age, &range, &newline) != EOF)
    
             if (((sex == 'F') && (age < 25) && (range == 1)))
              printf("%c %d %d\n", sex, age, range);
    
    
    
    
       }
          if (fclose(rawdat) == EOF)
             puts("Cannot close this file");
    
       //freopen ("H:\\sp3work\\SP3Project\\projecttext.txt","w",stdout);
                    //change to: \\\\student\\prn1 for printing
       /*
       space(28);                           // Start of Heading layout
       printf("CUSTOMER SURVEY REPORT\n");
       space(28);
       bar(22);
    
       printf("\n");                        // Start of line #3
       space(22);
       printf("FEMALES");
       space(19);
       printf("MALES\n");                   // End of line #3
    
       space(14);                           // Start of line #4
       bar(23);
       space(2);
       bar(23);                             // End of line #4
    
       printf("\n");
       space(14);                           // Start of line #5
       printf("younger  range   older   younger  range   older\n");   // End of line #5
    
       printf("\n");
       space(14);                          // Start of line #6
       printf("than 25 25 - 40 than 40  than 25 25 - 40 than 40\n");  // End of line #6
    
       space(4);                            // Start of line #7
       printf("LEAD TYPE ");
       bar(23);
       space(2);
       bar(23);
       printf(" TOTAL\n");                  // End of line #7
    
       space(4);                            // Start of line #8
       bar(9);
       space(50);
       bar(5);                              // End of line #8
    
       printf("\n\n");                      // Line #9 (used as a spacer between
                                            // title and main
       // End of heading
    
       // Start of main
       space(7);
       printf("REPEAT   999     999     999      999     999     999    999\n\n");
       space(0);
       printf("TELEVISION AD   999     999     999      999     999     999    999\n\n");
       space(1);
       printf("NEWSPAPER AD   999     999     999      999     999     999    999\n\n");
       space(5);
       printf("RADIO AD   999     999     999      999     999     999    999\n\n");
       space(0);
       printf("WORD OF MOUTH   999     999     999      999     999     999    999\n\n");
       space(8);
       printf("OTHER   999     999     999      999     999     999    999\n\n");
    
       space(8); bar(5); space(2); bar(4); space(4); bar(4); space(4); bar(4);
       space(5); bar(4), space(4); bar(4); space(4); bar(4); space(3); bar(4);
    
       printf("\n");
       space(8);
       printf("TOTAL  9999    9999    9999     9999    9999    9999   9999\n");
    
       space(8); bar(5); space(2); bar(4); space(4); bar(4); space(4); bar(4);
       space(5); bar(4), space(4); bar(4); space(4); bar(4); space(3); bar(4);
    
    
       //fclose (stdout);
        */
       printf("\n\n\nPress any key to continue");
       getch();
    }
    
       void bar(int number)
       {
          int count = 0;
          for (count = 1; count <= number; count++)
             putchar('=');
    
       }
    
       void space(int number)
       {
          int count = 0;
          for (count = 1; count <= number; count++)
             putchar(' ');
       }

  8. #8
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    I think I'll go for MK27's solution - It's the only one I completly understand at the moment

    Edit:

    Ok I've made a start with the following code:

    Code:
    {
          while (fscanf(rawdat, "%c %d %d &c", &sex, &age, &range, &newline) != EOF)
    
             if (sex == 'F'){
                if (age < 25) {
                   switch (range) {
                      case '1':
                      printf("%c %d %d\n", sex, age, range);
                    }
                 }
             }
       }
    I don't get any errors or warnings when the program compiles but also get no output, if I comment out the second if statement and the switch statement it does list all the 'F' respondents but leave either one or both in and I get no output apart from the "Press any key to continue" end statement
    Last edited by katipo; 12-08-2008 at 03:58 PM. Reason: additional info

  9. #9
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    Ok I worked out the problem, I don't need the single speech marks around the case '1':

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Just for fun:

    Code:
    #define Max 100;
    
    struct sets  {
       char sex;
       int age;
       int class;  //as in classification, not C++ classes.
    } set;    //with  this name "set", I've created one struct of type sets, called "set".
    
    /* now I make up an array of these structs, which I will cunningly name "arr" 
         it's size will be "Max"*, and will have elements from arr[0] through arr[Max - 1]/
    
    struct sets arr[Max];
    Now you load the array with your data, reading the data into the array, using it's
    structure's members: set.sex, set.age, and set.class

    Now we're ready to do a multi-key sort.

    Code:
    //a simple selection sort of a global struct array
    void sortIt(int num)   { //int num is the number of array entries you read from the file
    char ch;
    int i, j, age, class;
    
    for(i = 0; i < num - 1; i++)  {
       for(j = i + 1; j < num; j++)  {
          //start of primary key sort
          if(arr[i].sex > arr[j].sex])   {  //F < M
             //swap them, start by saving arr[i]'s members
             ch = arr[i].sex;
             age = arr[i].age;
             class = arr[i].class;
    
             //now assign arr[j] into arr[i]
             arr[i].sex = arr[j].sex;
             arr[i].age = arr[j].age;
             arr[i].class = arr[j].class;
    
             //and restore temp values into arr[j]
             arr[j]sex = ch;
             arr[j].age = age;
             arr[j].class = class;
          }        
          /* a sort by one key is coded. Simply add any other secondary keys, right here 
               this is all cut and paste of the above, except the first if statements (one more if 
               statement is needed for every sub key). */
          
          //start of secondary key sort
          //first step - is it needed at all?
          if(arr[i].sex == arr[j].sex)   {        //our first if statement
             if(arr[i].class > arr[j].class)   {   //our second if statement
                //This is our second sub key, and we have our two if statements, so we're good to go
                //swap them, start by saving arr[i]'s members
                ch = arr[i].sex;
                age = arr[i].age;
                class = arr[i].class;
    
                //now assign arr[j] into arr[i]
                arr[i].sex = arr[j].sex;
                arr[i].age = arr[j].age;
                arr[i].class = arr[j].class;
    
                //and restore temp values into arr[j]
                arr[j]sex = ch;
                arr[j].age = age;
                arr[j].class = class;
             }        
          }
       }
    }


    Want to add yet another sort key? It's all copy and paste, except for the if statements at the top of that key. (If you had more than two keys I might make the swap a separate function to avoid the repetition of code). The key code must be in order of their hierarchy: First key must go first, second key must go second, etc.

    I haven't run this code, so it might have bugs in it, but you should get the idea.

    Time for my coffee
    Last edited by Adak; 12-08-2008 at 06:38 PM.

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Adak -- I don't think the OP wanted it sorted (but I guess that's what "Just for fun" is)?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    The description could easily be handled by a multi-key sort, and then a simple tally.

    The first column represtents Male or Female the second Age and the third is a Selection. What I have to do is populate an array so all females under 25 who answered one are added together, all females under 25 who answered two are added together, so on, and so on.

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Adak View Post
    The description could easily be handled by a multi-key sort, and then a simple tally.
    Alright, another neat thing I am learning today.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #14
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    This looks kind of like an iterative bubble sort...so the array ends up with all the M at one end and all the F at the other, right?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MK27 View Post
    This looks kind of like an iterative bubble sort...so the array ends up with all the M at one end and all the F at the other, right?
    Yes, and then sorted on class - however, I think the sort is broken, in that it should only go to the "class" sorting if the sex is the same.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 11-25-2008, 01:50 AM
  2. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  3. Code: An auto expanding array (or how to use gets() safely).
    By anonytmouse in forum Windows Programming
    Replies: 0
    Last Post: 08-10-2004, 12:13 AM
  4. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  5. code doesnt flip array
    By noob2c in forum C Programming
    Replies: 3
    Last Post: 03-29-2003, 09:54 AM