CSCI 160: Fall 2018 Final Exam
Sections F18N01-F18N04 (Dr. Wessels)

Question Mark
Remembering to write your name!
[1 mark]
 
1. Input/output, error checking
[11 marks]
 
2. Scopes and parameter passing
[11 marks]
 
3. Nested loops:
[11 marks]
 
4. Null-terminated character arrays:
[11 marks]
 
5. Functions and arrays:
[11 marks]
 
6. Arrays of structs:
[11 marks]
 
7. Pointers:
[11 marks]
 
8. Recursion:
[11 marks]
 
9. File I/O:
[11 marks]
 
Exam Total

[100 marks]

 

Question 1: Input, output, and error checking [11]

Implement the obtainData function prototyped below.
float obtainData(long min, long max, long &userVal);

// First, obtainData gets the user to provide an integer value
//     in the range min..max (inclusive).  It checks the value
//     is an integer and is in the correct range, gives an
//     appropriate error message if not, and repeats until the
//     user provides a suitable value
// After the valid integer value has been obtained, the function
//     then gets the user to enter a float that is greater than
//     the integer value they provided in the first step.  Again,
//     appropriate error messages are provided and the process
//     repeats until a valid number is obtained.
// Finally, the function stores the integer value in parameter userVal,
//     and returns the floating point number obtained.
// a typical call might look like
//     x = obtainData(13, 27, y);

Sample solution
float obtainData(long min, long max, long &userVal)
{
   int scanC;
   long val;
   do {
      printf("Enter a number in the range %ld to %ld\n", min, max);
      scanC = scanf("%ld", &val);
      if (scanC < 1) {
         printf("That was not a number, please try again\n");
         scanf("%*s");
      } else if ((val < min) || (val > max)) {
         printf("%ld is not in the range %ld to %ld, please try again\n", val, min, max);
      }
   } while ((scanC < 1) || (val < min) || (val > max));

   float val2;
   do {
      printf("Enter a number bigger than %ld\n", val);
      scanC = scanf("%g", &val2);
      if (scanC < 1) {
         printf("That was not a number, please try again\n");
         scanf("%*s");
      } else if (val2 <= val) {
         printf("%g is not bigger than %ld, please try again\n", val2, val);
      }
   } while ((scanC < 1) || (val2 <= val));

   userVal = val;
   return val2;
}

Question 2: Scopes and parameter passing [11]

Show the precise and complete output from the following program:
#include <cstdio>

const int a = 1;
const int y = 5;
const int x = 8;

void f(int x, int &y);

int main()
{
   const int y = 3;
   int a = 7;
   printf("main1: y(%d), a(%d), x(%d)\n", y, a, x);
   f(y, a);
   printf("main2: y(%d), a(%d), x(%d)\n", y, a, x);
   f(x, a);
   printf("main3: y(%d), a(%d), x(%d)\n", y, a, x);
}

void f(int x, int &y)
{
   if (x > 5) {
      for ( ; y < 9; y++) {
          printf("f1:    y(%d), a(%d), x(%d)\n", y, a, x);
          x--;
      }
   } else {
      for (int y = 1; y < x; y++) {
          printf("f2:    y(%d), a(%d), x(%d)\n", y, a, x);
      }
   }
}

Sample solution
main1: y(3), a(7), x(8)
f2:    y(1), a(1), x(3)
f2:    y(2), a(1), x(3)
main2: y(3), a(7), x(8)
f1:    y(7), a(1), x(8)
f1:    y(8), a(1), x(7)
main3: y(3), a(9), x(8)

Question 3: Nested loops [11]

(i) Show the output from the code segment below
    for (int i = 1; i < 4; i++) {
       printf("row %d: ", i);
       for (int j = i; j < 8; j++) {
           printf("%4d", (10*j+i));
           if (j == 7) {
              printf("\n");
           }
       }
   }
(ii) Show the output from the code segment below
   for (int i = 1; i < 4; i++) {
       printf("row %d: ", i);
       int j = i;
       do {
           printf("%d, ", (10*j+i));
           j = j+2;
       } while (j < 8);
       printf("\n");
   }

Sample solution
row 1:   11  21  31  41  51  61  71
row 2:   22  32  42  52  62  72
row 3:   33  43  53  63  73

row 1: 11, 31, 51, 71, row 2: 22, 42, 62, row 3: 33, 53, 73,

Question 4: Null-terminated character arrays [11]

(i) Write the repstr function described by the prototype and comments below. You can assume the cstdio, cstring, cstdlib, and cctype libraries have all been included.
// assuming str contains a null terminated character array, and is sufficiently
//    large, replace the current contents of str with n copies of the string
// e.g. suppose myStr currently contains "hello",
//    then repstr(myStr,3) would change its contents to "hellohellohello"
void repstr(char str[], int n);
(ii) Write a main routine that does the following:

Sample solution
void repstr(char str[], int n)
{
   // make a temporary copy of str, then append the copy to the original n times
   int sz = strlen(str);
   char *str2 = new char[sz + 1];
   if (!str2) {
      return;
   }
   strcpy(str2, str1);
   for (int i = 0; i < n; i++) {
       strcat(str1, str2);
   }
   delete [] str2;
}

int main(int argc, char *argv[]) { if (argc > 2) { int n = atoi(argv[2]); if (n > 0) { int size = n * strlen(argv[1]) + 1; char *res = new char[size]; if (res) { repstr(res, n); printf("%s\n", res); delete [] res; } } } }

Question 5: Functions and arrays [11]

Write the contentSwap function described with the prototype below.
// assuming both arrays are large enough, swap the first N elements
//    of arr1 with the first N elements of arr2
// e.g. long data[7] = { 1, 2, 3, 4, 5, 6, 7 };
//      long stuff[5] = { 10, 20, 30, 40, 50 };
//      contentSwap(data, stuff, 3);
// new contents of the arrays should be
//      data:  { 10, 20, 30, 4, 5, 6, 7 };
//      stuff: { 1, 2, 3, 40, 50 };
void contentSwap(long arr1[], long arr2[], int N);

Sample solution
void contentSwap(long arr1[], long arr2[], int N)
{
   for (int i = 0; i < N; i++) {
       long tmp = arr1[i];
       arr1[i] = arr2[i];
       arr2[i] = tmp;
   }
}

Question 6: Arrays of structs [11]

Suppose we have a program with the following struct definition and prototypes:
// represent a time as three integers (hour 1-12, minute 0-59, second 0-59)
struct TimeOfDay {
   int hour, minute, second;
};

// fills an array of times with values supplied by the user
void fill(TimeOfDay arr[], int numTimes);

// prints an array of times, one per line,
//    formatting each time as hh:mm:ss (e.g. 11:04:59)
void print(TimeOfDay arr[], int numTimes);

(i) Write a main routine that declares an array of 100 TimeOfDays, calls fill to fill it and print to print it.

(ii) Write the print routine described with the prototype above.

Sample solution
int main()
{
   TimeOfDay array[100];
   fill(array, 100);
   print(array, 100);
}

void print(TimeOfDay arr[], int numTimes) { for (int i = 0; i < numTimes; i++) { printf("%02d:%02d:%02d\n", arr[i].hour, arr[i].minute, arr[i].second); } }

Question 7: Pointers [11]

(i) Rewrite the swap function below to use pointers instead of pass-by-reference to achieve the same effect.
void swap(int &x, int &y)
{
   int tmp = x;
   x = y;
   y = tmp;
}

(ii) Rewrite the display function below to expect a pointer to a coord struct (the definition of the coord struct is provided) instead of a copy of a struct.
// x and y coordinates represented as integers
struct coord {
    int x, y;
};

void display(coord c)
{
   printf("(%d, %d)\n", c.x, c.y);
}

(iii) Write a C++ code segment that declares arr as a pointer to an int, uses new to dynamically allocate an array of 13 floats and store the result in arr, and displays an error message if arr is null afterwards.

(iv) Write a C++ code segment that tests if arr is null, and deallocates the associated storage if it is not.

Sample solution
void swap(int *x, int *y)
{
   int tmp = *x;
   *x = *y;
   *y = tmp;
}

void display(coord *c) { if (c) { printf("(%d,%d)\n", c->x, c->y); } }
int *arr = new int[13]; if (arr == NULL) { printf("Error: could not allocate storage\n"); }
if (arr == NULL) { // do whatever } else { delete [] arr; }

Question 8: Recursion [11]

Write the recursive findSmallest function described with the prototype below.
// findSmallest takes as parameters an array of floats,
//    a starting position in the array, and the number of elements in the array
// it recursively finds the smallest value (in positions start through size-1)
//    and returns the position in which the value was found,
//    or -1 if there is no value (i.e. if start >= size)
// e.g. float arr[6] = { 10, 0, 3, 9, 1, 16 };
//      pos = findSmallest(arr, 2, 6);   // pos should be 4
int findSmallest(float arr[], int start, int size);

Suggested algorithm:
   if size <= start return -1
   if size == start+1 return start
   otherwise
      call findSmallest(arr, start+1, size) to get the location
           of the smallest value in the rest of the array
      then compare what's in arr[start] to what's in the
           array in that position to figure out where the
           overall smallest value is

Sample solution
int findSmallest(float arr[], int start, int size)
{
   if (size <= start) {
      return -1;
   } else if (size == (start+1)) {
      return start;
   }
   int pos = findSmallest(arr, start+1, size);
   if ((pos >= 0) && (arr[pos] < arr[start])) {
      return pos;
   }
   return start;
}

Question 9: File I/O [11]

Suppose we have a data file, Names.txt, that contains the following text:
1 doos     Scoobert (Scooby) Doo
2 blaked   Daphne Blake
3 dinkleyv Velma Dinkley
4 rogersn  Norville (Shaggy) Rogers
5 jonesf   Fred
Jones
6
If we run the following program (which reads the Names.txt file), show the precise output generated:
#include <cstdio>

const int MaxLen = 256;

int main()
{
   FILE *fpin;
   fpin = fopen("Names.txt", "r");
   if (fpin != NULL) {
      while (!feof(fpin)) {
         char word[MaxLen], line[MaxLen];
         long id;
         if (fscanf(fpin, "%ld", &id) > 0) {
            fscanf(fpin, "%s", word);
            fgets(line, MaxLen-1, fpin);
            printf("Id %ld (%s) %s", id, word, line);
         } else {
            fgets(line, MaxLen-1, fpin);
            printf("Non-id at start of line: %s", line);
         }
      }
      fclose(fpin);
   }
}

Sample solution
Id 1 (doos)      Scoobert (Scooby) Doo
Id 2 (blaked)    Daphne Blake
Id 3 (dinkleyv)  Velma Dinkley
Id 4 (rogersn)   Norville (Shaggy) Rogers
Id 5 (jonesf)    Fred
Non-id at start of line: Jones
Id 6 (jonesf) Jones

  CSCI 160 Exam Quick Reference Sheet: Sections F15N01-F15N04
Comments:    Single line //       or Multi-line  /* ....
                                                    .... */
C++ operators
=============
Arithmetic operators:     +   -   *   /   %   ++  --
Assignment operators:  =  +=  -=  *=  /=  %=
Boolean operators:     &&  ||  !  ==  !=  <=  >=  <  >

Data Types
=======================================================
Data        Keywords             Literal Examples    Special values
integers:   short, int, long     3, -200, 0          INT_MAX, INT_MIN  (climits library)
reals:      float, double        3.14, -0.0003       FLT_MAX, FLT_MIN  (cfloat  library)
character:  char                 'x'                 \'  \"  \\  \t \n  \0
boolean:    bool                 true, false

Sample variable declarations (with/without initialization)
==========================================================
int    i;       int    i = 3;
char   c;       char c = 'Q';   char c = '\n';
bool   b;       bool b = true;
long arr[5];    long arr[5] = { 0, 0, 0, 0, 0 };   // array assignment only valid
char str[10];   char str[] = "some text";          //    at point of declaration

Sample constant declarations
============================
const double Pi = 3.1415;
const char[] ErrMsg = "Error: something terrible happened!\n";

Sample enumerated type definitions
==================================
enum Weekdays { Sun, Mon, Tue, Wed, Thu, Fri, Sat };
enum Commands { Quit = 'Q', Continue = 'C', Print = 'P' };

Sample input with scanf, fgets, and getc (cstdio library)
=========================================================
scanf("%c", &x);  // read a character into char variable x
scanf("%d", &i);  // read an integer into int variable i
scanf("%ld", &n);  // read an integer into long variable n
scanf("%g", &f);  // read a real number into float variable f
scanf("%s", &a);  // read text into variable a (char[])
scanf("%*s");     // read and discard the next word of input
scanf("%[abc]", &x); // read an a, b, or c into variable x
scanf("%*[ \t\n]%c", &x); // skip tabs, spaces, and newlines and read next char into x
scanf("%4d", &i); // read a maxium of 4 digits into int variable i

Sample output with printf (cstdio library)        
==========================================        
printf("%c", x);  // print the contents of  char variable c
printf("%d", i);  // print the contents of int variable i
printf("%ld", n);  // print the contents of long variable n
printf("%g", f);  // print the contents of float variable f 
  // (%f gives fixed point, %e gives exponential notation, %g can do either)
printf("%5.2g, f); // print the contents of f with width 5, 2 decimal places
printf("%s", a);  // print the contents of character array a

Sample file i/o with fgets, fscanf, fprintf, getc, and ungetc (all cstdio)
==========================================================================
// examples of opening / closing
FILE *fpin = fopen("filename", "r");  "r", "w", or "a"
if (fpin == NULL) {
   // failed to open
}
fclose(fpin);  // only if file successfully opened

// examples of reading from file
fscanf(fpin, "%4d", &i); // from the file specified, read a maxium of 4 digits into int variable i
fgets(arr, 100, fpin); // read the rest of the line (up to 100 chars max) into the char array
x = getc(fpin);  // read a single character into char variable x
ungetc(c, stdin); // take char c and push it into the input buffer

// testing for end of file
if (feof(fpin)) {
   // end of file has been detected
}

// examples of writing to file
fprintf(fpout, "%4d", i);

Some useful library functions and constants
===========================================
cctype                 cfloat                   cmath
------                 ------                   -----
bool isalpha(char)     FLT_MIN, FLT_MAX         double ceil(double)
bool isalnum(char)     DBL_MIN, DBL_MAX         double floor(double)
bool isdigit(char)                              double fabs(double)
bool islower(char)     climits                  double log(double)
bool isupper(char)     -------                  double pow(double, double) 
bool ispunct(char)     CHAR_MIN, CHAR_MAX       double cos(double)
bool isspace(char)     SHORT_MIN, SHORT_MAX     // also acos, sin, asin, tan, atan
char tolower(char)     INT_MIN, INT_MAX         double sqrt(double)
char toupper(char)     LONG_MIN, LONG_MAX

cstring                            cstdlib
-------                            -------
char* strcat(char*, char*)         int abs(int)
char* strncat(char*, char*, int)   int atoi(char*)
char* strcpy(char*, char*)         float atof(char*)
char* strncpy(char*, char*, int)   void srand(time(NULL)) // needs ctime lib 
int   strcmp(char*, char*)         int rand(int)
int   strncmp(char*, char*, int)
int   strlen(char*)

Sample control structures
=========================
if (expr) {                  // works on short, int, long,      for (x = 1; x < 9; x++) {
   .......                   //    char, or enum values             ....
} else if (expr) {           switch (expr) {                    }
   ........                     case value1:
} else {                            .....                       while (x < 9) {
   ........                         break;                          ....
}                               case value2:                        x++;
                                    .....                       }
// is X between 3 and 9?            break;
if ((3 < X) && (X < 9)) {       default:                        do {
   // yes it is                     .....                           ....
} else {                            break;                          x++;
   // no it isn't            };                                 } while (x < 9);
}
         Sample function prototypes and implementations         Sample calls
         ==============================================         ============
void swap(int &a, int &b);      float calc(int x, float f)      int main()
......                          .....                           {
void swap(int &a, int &b)       float calc(int x, float f)         int i = 1;
{                               {                                  int j = 2;
    int temp = a;                  float result = x * f;           swap(i, j);
    a = b;                         return result;                  float f = calc(i, 2.5);
    b = temp;                   }                                  int array[20];
}                                                                  initArray(array, 20);
                                                                }
void initArray(int arr[], int size)
{                                  
   for (int i = 0; i < size; i++
       arr[i] = 0;
}              

Pointer examples
================
int i;       // an integer variable i
int *iPtr;   // iPtr can point at integers in memory
iPtr = &i;   // iPtr now points at variable i (& takes the address of i)
(*iPtr) = 3; // store 3 whereever iPtr points in memory

Sample function prototype with a pointer passed by reference
============================================================
void doSomething(int* &ptr);

Dynamic memory allocation and deallocation
==========================================
using new/delete            using malloc/free
----------------            -----------------
int *i = new int;           int *i = (int*)malloc(sizeof(int);        // alloc new int 
delete i;                   free i;                                   // free the int
float *f = new float[10];   float *f = (float*)malloc(sizeof(float)); // alloc new arr of floats
delete [] f;                free f;                                   // free the array
// remember to test for NULL after any call to new or malloc

Sample struct definition and use       
===================================  
struct Info {                         Info i; 
   char initials[2];                  i.id = 0;
   int id;                            i.value = -34.216;
   float value;                       i.initials[0] = 'D';
};

The C++ string class (using the  library)
====================
std::string str; // declare a string variable str
str = "blah blah blah"; // assign text to a string
printf("%s", str.c_str()); // print the string contents
str[3] = 'x'; // change the fourth character in the string to x