Note to Students: This file contains sample solutions to the term test together with the marking scheme and comments for each question. Please read the solutions and the marking schemes and comments carefully. Make sure that you understand why the solutions given here are correct, that you understand the mistakes that you made (if any), and that you understand why your mistakes were mistakes. Remember that although you may not agree completely with the marking scheme given here it was followed the same way for all students. We will remark your test only if you clearly demonstrate that the marking scheme was not followed correctly. For all remarking requests, please submit your request in writing directly to your instructor. For all other questions, please don t hesitate to ask your instructor during office hours or by e-mail. Question 1. [15 marks] For each part of this question, state what will happen when the code is compiled and run (use the space to the right of the code). Some of the code contains bugs, which you should identify. Some of the code produces output, which you should write down. Some of the code may do a bit of both... Part (a) [2 marks] const int x = 10; int y = 5; if (x = 20) y++; printf("x = %d, y = %d\n", x, y); error: assignment of read-only variable x ( x = 20 tries to modify a constant) Outcome [1]: stating the code produces an error Error [1]: correctly identifying the error Marker s Comments: Many students thought the only mistake was that there is an assignment statement inside the if. Part (b) [1 mark] int x = 99L; int y = 0xa9s; printf("%d, %d\n", x, y); error: invalid suffix "s" on integer constant (0xa9s is not a valid literal) Outcome [1]: stating the code produces an error Error [1]: correctly identifying the error Page 1 of 7
Part (c) [1 mark] int x = -1; if (x) else printf("this is true.\n"); printf("i don t think so!\n"); Prints This is true. [1]: all-or-nothing Part (d) [2 marks] char x = 500; if (x == 500) else printf("this is true.\n"); printf("i don t think so!\n"); Prints I don t think so! [1]: all-or-nothing Part (e) [2 marks] int x = 20; if (x < 10) printf("too small!\n"); printf("try again...\n"); else printf("okey-dokey.\n"); error: expected expression before else (else with no matching if because of missing curly braces around if body) Outcome [1]: stating the code produces an error Error [1]: correctly identifying the error Marker s Comments: Many students did not realize there were missing curly braces. Part (f) [2 marks] int i = 3; do printf("%d...\n", i); while (--i > 0); printf("go!\n"); Page 2 of 7
Prints 3... 2... 1... Go! 1 per error (missing or additional or incorrect output) Marker s Comments: Some students did not include the... after each number. Part (g) [2 marks] int x = 10, *y = &x, z = 20; printf("%d, %d, %d\n", x, *y, z); *y = 5; printf("%d, %d, %d\n", x, *y, z); y = &z; printf("%d, %d, %d\n", x, *y, z); Prints 10, 10, 20 5, 5, 20 5, 20, 20 1 per error (missing or additional or incorrect output) Part (h) [3 marks] double a[] = -3.1415, 0, 1.5, 2.7e14, 9999; double *p = a; while (*p++!= 9999) printf("\n"); printf("%g, ", *p); Prints 0, 1.5, 2.7e14, 9999, 1 per error (missing or additional or incorrect output) Page 3 of 7
Question 2. [15 marks] Part (a) [5 marks] Complete the function below so that it satisfies its documentation. /* Print a description of a number grade: "Invalid." if grade is negative or greater * than 100; "Pass!" if grade is 50 to 100; "Fail..." if grade is 0 to 49. */ void describe(int grade) if (grade < 0) printf("invalid.\n"); else if (grade < 50) printf("fail...\n"); else if (grade <= 100) printf("pass!\n"); else printf("invalid.\n"); Output [3]: Syntax [2]: correct strings printed in every case correct C syntax (in particular, 1 for missing parentheses) Part (b) [5 marks] Write code below to read 50 values from the user and store them into the array list. Assume that the input is error-free. Remember to declare any extra variables you use. double list[50]; int i; for (i = 0; i < 50; ++i) scanf("%lf", list + i); Loop [2]: correct loop structure scanf [2]: correct use of scanf (correct specifier and argument) Syntax [1]: correct C syntax overall (including variable declarations) Marker s Comments: common error [ 1.5]: reading in the wrong type (e.g., int) instead of double common error [ 0.5]: conversion specifier "%f" or "%g" or "%e" instead of "%lf" common error [ 1]: other incorrect conversion specifiers (e.g., "%d") common error [ 0.5]: using list[i] instead of &list[i] as argument to scanf common error [no penalty]: using, instead of ; to separate each part of a for loop Page 4 of 7
Part (c) [5 marks] Fill in the parameters and body of function decompose according to its documentation. /* This function takes a long argument representing a 10-digit telephone number and * three pointers to ints. It assigns the area code (the first 3 digits of the phone * number) to the memory location given in the first pointer, the next 3 digits of the * phone number to the second pointer, and the last 4 digits of the phone number to * the last pointer. See further below for an example of how it is called. Assume * that the area code never starts with 0, and neither does the 7-digit base number. */ void decompose( long number, int *area, int *first, int *second ) *area = number / 10000000; *first = (number % 10000000) / 10000; *second = number % 10000; int area, first, second; decompose(4169783707l, &area, &first, &second); printf("(%d) %d-%4d", area, first, second); // The statement above prints "(416) 978-3707" (without quotes). Parameters [2]: correct parameter declarations Body [3]: correct function body Page 5 of 7
Question 3. [15 marks] Write a complete program to censor all digits from a file. When it is executed, your program will: ask the user for input and output filenames (each filename will be less than 80 characters long); copy the contents of the input file to the output file, except that every digit (characters 0 to 9 ) in the input file is replaced by the character # in the output file. For example, if the input file contains: In the next 60 minutes, you must complete all 3 questions on the 10 pages of this test... then the output file will contain: In the next ## minutes, you must complete all # questions on the ## pages of this test... after running your program. Your answer must be a complete program, i.e., it must have a main function, appropriate #include directives, etc. Part of your grade will be for style and design, i.e., it s not enough for your code to work correctly, it must also be well written think about helper functions, preprocessor constants, etc. In particular, use your main function to handle all user interaction and opening/closing files, and write a helper function to handle copying data from one file to the other while replacing digits. Your program should produce an appropriate error message if it is unable to open one of the files, but you do not have to handle read/write errors while processing the files. Relax! This is not as difficult as it might seem. Just take it one step at a time. #include <stdio.h> #include <stdlib.h> #define NAME_LEN 80 /* Ask the user for a file name, open the file in the specified mode, and * return a pointer to the file. Stop the program in case of error. */ FILE *open_file(const char *prompt, const char *mode) FILE *file; char name[name_len]; printf("%s file name: ", prompt); scanf("%s", name); // assume no error during user input if ((file = fopen(name, mode)) == NULL) fprintf(stderr, "Unable to open %s\n", name); exit(exit_failure); return file; Page 6 of 7
/* Process input file in as described in the question. Write the output * to file out. Precondition: in!= NULL, out!= NULL. */ void censor(file *in, FILE *out) char c; while (fscanf(in, "%c", &c) == 1) if ( 0 <= c && c <= 9 ) c = # ; fprintf(out, "%c", c); /* Get file names from user, open them, and call censor on them. */ int main(void) FILE *in = open_file("input", "r"), *out = open_file("output", "w"); censor(in, out); fclose(out); fclose(in); return EXIT_SUCCESS; Idea [5]: clear attempt to carry out the correct algorithm even if the code is terribly designed and riddled with syntax errors Design [3]: well designed code, with at least one helper function independently of the correctness or syntax Syntax [7]: correct C syntax throughout (take off only 0.5 marks for small things like missing parentheses or semicolons) Marker s Comments: common error [ 1]: Idea: reading only the first character (i.e., missing loop) [Instructor s Comment: This is a serious error! The markers were very generous to penalize this only by 1. Make sure you understand why this is wrong!] common error [ 1]: Idea: not asking user for input and output file names common error [ 1]: Idea: not checking for errors when opening files common error [ 1]: Design: no preprocessor constant common error [ 1]: Design: no helper function common error [ 0.5]: Design: placing user interaction and file opening/closing in helper functions common error [ 0.5]: Syntax: not closing files common error [ 0.5]: Syntax: not checking if opening files causes an error common error [ 0.5]: Syntax: defining helper function after main without a declaration common error [ 0.5]: Syntax: comparing character to int value 0 instead of char value 0 common error [ 0.5]: Syntax: comparing fscanf return value against something other than NULL common error [ 0.5]: Syntax: reading user input into a variable of type FILE * instead of char * common error [ 0.5]: opening files multiple times (lack of understanding of how to use files) Page 7 of 7