CS140 Midterm 1 Solutions

Fall 2010


  1. (4 points) Declare a constant named MONTHS with the value 12.
    #define MONTHS 12
  2. (3 points) What character terminates a C-style string?
    The null character, '\0'
  3. (3 points) Declare a variable named first_name that can store a name with up to 10 characters (e.g., it should be able to store the name "elisabetha").
    char first_name[11];
  4. (5 points) Write a command to compile a source file named search.c into an executable named search using the gcc compiler.
    gcc -o search search.c
  5. (8 points) Write a struct for an animal and name it Animal. The struct should contain the following fields:

    struct Animal {
      char common_name[16];
      char *latin_name;
      int year_discovered;
      int mammal;
    };
    
  6. (8 points) Answer the following questions:

    1. Declare a variable named dog which is an Animal struct.
      struct Animal dog;
    2. Assign 1990 to the dog's year_discovered field.
      dog.year_discovered = 1990;
    3. Copy a string with the value "labradoodle" to dog's common_name field.
      strcpy(dog.common_name, "labradoodle");
  7. (24 points) Consider the following declarations:
           char name[35];              char *new_name;
           char first_name[10];        char **parts;
           char last_name[20];         float speed;
           char *min_name;
          
    Write statements to accomplish the following tasks:

    1. copy the string pointed to by min_name to first_name. You may assume that min_name has fewer than 10 characters.
      strcpy(first_name, min_name);
    2. print the lesser (i.e., earlier in alphabetical order) of the two strings pointed to by min_name and new_name in a left-justified field of 20 characters.
         if (strcmp(min_name, new_name) < 0)
           printf("%-20s\n", min_name);
         else
           printf("%-20s\n", new_name);
      
    3. print speed in a right-justified field of 8 characters with 3 digits allocated to the part after the decimal point.
      printf("%8.3f\n", speed);
    4. do a safe copy of the string in new_name to min_name (by doing a safe copy I mean you will need to malloc memory for min_name before performing the copy).
      min_name = (char *)malloc(sizeof(char)*(strlen(new_name)+1));
      strcpy(min_name, new_name);
      
    5. print the combined length of first_name and last_name in a right-justified field of 3 digits.
      printf("%3d\n", strlen(first_name) + strlen(last_name));
    6. malloc an array of 50 string pointers and assign the address of the newly created array to parts.
      parts = (char **)malloc(sizeof(char *)*50);
    7. do a safe copy of the string in new_name to the fifth element of parts.
      parts[4] = (char *)malloc(sizeof(char)*(strlen(new_name)+1);
      strcpy(parts[4],new_name);
      
    8. create a string of the form "last_name, first_name" and store it in name (for full credit you must build the string in name rather than creating it separately and then copying it to name).
      strcpy(name, last_name);
      strcat(name, ", ");
      strcat(name, first_name);
      
  8. (15 points) Consider the following code:
         main(int argc, char *argv) {
           FILE *input_file;
           char buffer[101];
           int num_lines;
           int price
           double quantity;
           ...
          }
         
    Assume that the above program takes two command line arguments. The first argument is the name of the input file and the second argument is the number of lines in the file.

    1. Write a fragment of code to open the input file, test whether or not it was opened, and, if it failed to open, prints an error message that explains why it failed to open.
      input_file = fopen(argv[1], "r");
      if (input_file == NULL) 
          perror(argv[1]);
      
    2. Write an fscanf statement that reads the first two fields from input_file into price and quantity respectively.
      fscanf(input_file, "%d %lf", &price, &quantity);
    3. Write a statement that converts the second command line argument to an integer and assigns it to num_lines. Your statement should check to see whether or not it was possible to convert the command line argument to an integer. If it failed, you should print an error message that reads "xxxx: could not be converted to an integer", where "xxxx" is the value of the second command line argument.
      if (sscanf(argv[2], "%i", &num_lines) != 1) 
        printf("%s: could not be converted to an integer\n", argv[2]);
      
  9. (10 points) Consider the following code:

         int x;
         char month[6];
         char *string_ptr;
         int *int_ptr;
    
         strcpy(month, "febr.");
         x = 20;
         string_ptr = month;
         int_ptr = &x;
         *int_ptr = 40;
         
    Also suppose that the above variables are assigned the following memory layout:
    	  x: 0x600 
              month: 0x604
              string_ptr: 0x60c					
              int_ptr: 0x610					
         
    After the above code executes, what is the value of:

    1. x: 40
    2. month: "febr."
    3. string_ptr: 0x604
    4. int_ptr: 0x600

  10. (20 points) Write a main program with the following characteristics:

    1. it takes two command line arguments. The first command line argument represents the input file name, and the second command line argument represents a word that we are trying to find in the file.
    2. it allocates an inputstruct for the input file
    3. for each line in the input file it prints the number of times the search word appears on the line, prefixed with the number of that line
    4. it releases the inputstruct when the file is fully read
    5. at the end of the program it prints a count of the total number of times that the word appears in the file. The line printed should have the form:
      xxxx appears dd times
      
      where xxxx is your search word and dd is the number of times it appears in the file. Do not worry about specifying field widths in your print statement.
    6. it does no error checking
    7. it does not show me any include statements

    As an example, suppose main is placed in an executable named search, and you type the command

         search words.txt do
         
    if words.txt contains the following lines:
         how do you do
         today and how
         do 
         you think you will
         do tomorrow?
         
    your function should produce the output:
         1: 2
         2: 0
         3: 1
         4: 0
         5: 1
         do appears 4 times
         
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include "fields.h"
    
    main(int argc, char *argv[]) {
      IS inputFile;               // the input file
      // the total number of times the search word appears in the file
      int totalWordCount = 0;     
      // the number of times the search word appears on the current line
      int lineWordCount;
      int i;
      
      /* open the file for reading. Normally we would check to see
         whether or not new_inputstruct returned NULL to indicate a
         problem with opening the file, but the problem told you not
         to do any error checking */
      inputFile = new_inputstruct(argv[1]);
    
      while (get_line(inputFile) != EOF) {
        lineWordCount = 0;
        /* count the number of times the search word appears on the
           current line */
        for (i = 0; i < inputFile->NF; i++) 
          if (strcmp(inputFile->fields[i], argv[2]) == 0)
    	lineWordCount++;
        printf("%d: %d\n", inputFile->line, lineWordCount);
        /* update the total word count to reflect the number of times
           the word was found on this line */
        totalWordCount += lineWordCount;
      }
      printf("%s appears %i times\n", argv[2], totalWordCount);
    }