Week 7 Laboratory — Sample Solutions

  1. mary.c

    // mary.c: concatenate all the command-line args into a single string on the heap
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char *argv[]) {
       int total = 0;
       int retval = EXIT_SUCCESS;
       int i;
       for (i=0; i<argc; i++) {
          total += strlen(argv[i]);
       }
       total++; // include space for the '\0'
       char *heap = (char *)malloc(total * sizeof(char));
       if (heap != NULL) {
          strcpy(heap, argv[0]);
          for (i=1; i<argc; i++) {
             strcat(heap, argv[i]);
          }
          printf("%s\n", heap);
          free(heap);
       } else {
          fprintf(stderr, "No memory .. aborting\n");
          retval = EXIT_FAILURE;
       }
       return retval;
    }
    

    Anyone with a better or more interesting solution?

  2. heapsum.c

    // heapsum.c: put the cmd-line numerical args onto the heap and sum
    #include <stdio.h>
    #include <stdlib.h>
    
    void heapupload(int *heap, int argc, char *argv[]);
    
    int  heapsum(int *heap, int n);
    
    int main(int argc, char *argv[]) {
       int retval = EXIT_SUCCESS;
    
       if (argc >= 2) {        // there must be at least one arg
          int *heap = (int *)malloc((argc-1) * sizeof(int));
          if (heap != NULL) {
             heapupload(heap, argc, argv);
             printf("%d\n", heapsum(heap, argc-1));
             free(heap);
          } else {
             fprintf(stderr, "%s: no memory ... aborting\n", argv[0]);
             retval = EXIT_FAILURE;
          }
       }
       return retval;
    }
    
    void heapupload(int *heap, int argc, char *argv[]) { // ''upload'' argv[] onto heap
       int arg = 1;      // arg will be used to walk along the cmd line
                         // heap will be used to walk along the heap
       while (arg<argc && sscanf(argv[arg], "%d", heap) == 1) {
                         // the scanf() has done the hard work here
                         // debug: printf("putting %d on the heap\n", *heap);
          arg++;         // next arg
          heap++;        // go to next heap position (modifying 'heap' is normally
                         // dangerous as it is what malloc returned and needs to
       }                 // be freed, but in a function it is okay)
    }
    
    int heapsum(int *heap, int n) { // sum n numbers in array heap
       int i;
       int sum = 0;
       for (i=1; i<=n; i++) {
          sum = sum + *heap++; // sum as you walk the heap
       }
       return sum;
    }
    

  3. llbuild.c

    // llbuild.c: create a linked list from user input, and print
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct node {
       int data;
       struct node *next;
    } NodeT;
    
    NodeT *makeNode(int);    // taken from the lecture
    void freeList(NodeT *);  // taken from the lecture
    
    NodeT *joinList(NodeT *, NodeT *);
    void printList(NodeT *);
    
    int main(void) {
       NodeT *all = NULL;
       int data;
    
       printf("Enter an integer: ");
       while (scanf("%d", &data) == 1) {
          NodeT *new;
          new = makeNode(data);
          all = joinList(all, new);
          printf("Enter an integer: ");
       }
       if (all != NULL) {
          printf("Finished: list is ");
          printList(all);
          freeList(all);
       } else {
          printf("Finished\n");
       }
       return EXIT_SUCCESS;
    }
    
    NodeT *joinList(NodeT *head1, NodeT *head2) {
    // either or both head1 and head2 may be NULL
       NodeT *cur;
       cur = head1;
       if (cur != NULL) {
          while (cur->next != NULL) { // cannot fail
             cur = cur->next;
          }
          cur->next = head2; // if head2 == NULL does nothing
       } else {
          head1 = head2;
       }
       return head1;
    }
    
    void printList(NodeT *head) {
       NodeT *cur;
       cur = head;
       while (cur != NULL) {
          printf("%d", cur->data);
          cur = cur->next;
          if (cur != NULL) {
             printf("->");
          }
       }
       if (head != NULL) {
          putchar('\n');
       }
    }
    

  4. llsum.c

    // llsum.c: create a linked list from numbers on stdin,
    //          and output their sum
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct node { 
       int data; 
       struct node *next;
    } NodeT;
    
    int    sumList(NodeT *);
    NodeT *insertTail(NodeT *, int); // taken from the lecture
    void   printList(NodeT *);       // as above
    void   freeList(NodeT *);        // taken from the lecture
    
    int main(void) {
       NodeT *lil = NULL;
       int dataGood = 1;
       int retval = EXIT_SUCCESS;
    
       int number;
       if (scanf("%d", &number) == 1) {
          int n;
          for (n=0; n<number; n++) {
             int data;
             if (scanf("%d", &data) == 1) {
                lil = insertTail(lil, data);
             } else {
                printf("Data missing\n");
                dataGood = 0;
             }
          }
          if (dataGood && n > 0) {
             printf("Linked list = ");
             printList(lil);
             printf("Total = %d\n", sumList(lil));
             freeList(lil);
          }
       } else {
          printf("No data\n");
          dataGood = 0;
       }
       if (!dataGood) {
          retval = EXIT_FAILURE;
       }
       return retval;
    }
    
    int sumList(NodeT *head) {
       NodeT *cur;
       int total = 0;
       cur = head;
       while (cur != NULL) {
          total = total + cur->data;
          cur = cur->next;
       }
       return total;
    }
    

  5. llord.c

    // llord.c: create a linked list from data on stdin,
    //          and report whether ordered/unordered
    //          assumes data is numerical
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct node { 
       int data; 
       struct node *next;
    } NodeT;
    
    int    isOrderedList(NodeT *);
    NodeT *insertTail(NodeT *, int);
    void   printList(NodeT *);
    void   freeList(NodeT *);
    
    int main(void) {
       NodeT *lil = NULL;
    
       int number;
       if (scanf("%d", &number) == 1) {
          int n;
          for (n=0; n<number; n++) {
             int data;
             if (scanf("%d", &data) == 1) {
                lil = insertTail(lil, data);
             }
          }
          if (n>0) {
             printf("Linked list = ");
             printList(lil);
             printf("List is ");
             if (isOrderedList(lil)) {
                printf("ordered\n");
             } else {
                printf("unordered\n");
             }
             freeList(lil);
          }
       }
       return EXIT_SUCCESS;
    }
    
    int isOrderedList(NodeT *head) {
       int ordered = 1;
       if (head != NULL) { // need at least 1 node
          NodeT *cur;
          cur = head;
          while (cur->next != NULL && ordered) { // walk the list
             if (cur->data > cur->next->data) {
                ordered = 0;                     // found unordered
             } else {
                cur = cur->next;
             }
          }
       }
       return ordered;
    }