CSC 161 Grinnell College Fall, 2011
 
Imperative Problem Solving and Data Structures
 
 

Laboratory Exercise on Basic I/O

Goals

The goal of this lab is to practice the concepts of and functions concerning input and output in the C programming language.

Lab Exercises

During this lab, you will gain familiarity with I/O, as well as learn some basic functions concerning I/O.

Move to the directory you use for this class, and create a directory for this lab.

Exercise 1: getchar and putchar

Download and save the file getchar-example.c to your current directory, compile it, and run it a few times to make sure you understand it. Recall that the single-character printing function putchar, like getchar, deals with a single character per call.

  1. What happens when you enter more than one letter? Why?
  2. How about if you do not enter a letter, but simply press enter?

    Recall that getchar gets a single character; blank space and newline characters are considered viable characters.

  3. Try to use the string ending character (press and hold the Ctrl key and d, and release both). What happens? Why?
  4. Why do you think the line
    putchar ('\n');
    is included?

    Like getchar, putchar takes a single character. The function putchar prints a single character to stdout.

  5. Modify the program to read a number using getchar, initialize the size of an array with the number you read, fill the array of characters with entered characters, and then print the string formed. (You may use printf to print the string.)

    Recall that getchar returns a character. In the previous lab, you learned about ASCII. Use what you learned to convert the numerical character into an integer.

  6. You can also modify the characters as they are inputted. Modify your function so that it sets each letter to the opposite case when placing it in the string. Note that <ctype.h> has functions that compare types and modify letter cases.

    Examples:

    • apple -> APPLE
    • AlPhAbEt -> aLpHaBeT
    • X-Ray -> x-rAY

Exercise 2: Programming with getchar

  1. Write a program that prints a prompt for input, then prints the number of characters entered. Did your program print the number of characters as you expected?
  2. As you learned in the lab on characters and strings, letters, numbers, and punctuation are not the only types of characters; tabs, spaces, and newline characters also are characters. Modify your program so that the program ends and prints the number of characters when some form of punctuation is entered.

    Hint: be sure to include <ctype.h>.

  3. Modify your program to also print the number of uppercase and lowercase letters in your input.

Exercise 3: Practice with printf

  1. As you have learned previously, it is important to pay close attention to variable types, and you may have seen errors that occur due to a type mismatch in a function. Look at the following code, where each printf statement uses the wrong type for the declared variable.
    #include <stdio.h>
    
    int
    main()
    {
      int x = 9, y;
      double s = 13.86;
      char * word = "computer";
      char ch = word[5];
      
      y = (int) s;
    
      printf ("\tThe value of x is %lf.\n", x);
      printf ("\tThe value of y is %f.\n", y);
      printf ("\tThe value of s is %d.\n", s);
      printf ("\tThe value of word is %c.\n", word);
      printf ("\tThe value of ch is %s.\n", ch);
      printf ("\tThe value of ch is %d.\n", ch);
    
      return 0;
    }
    
    • Will the code compile? Save the program to a file in your directory and check. Run the program. Do any line(s) cause the program to segfault? Why?

    • Fix the line(s) that prevents the code from completing, and run the code. Explain why you get each incorrect value. How are integers, doubles, and floats treated by each other? How is a character different from a string?

      Hint: consider how each variable type is stored and evaluated.

    • Change the printf statements so the correct values are printed when the program is run, and check that your changes fixed the code.

    • Look at the following two lines of code:

      printf ("\tThe value of s is %lf.\n", s);
      printf ("\tThe value of s is %f.\n", s);

      Will these two lines print the same or different output? Why?

    • Make sure both lines are in your code, compile, and run. Did the output match your expectations? If not, why did the code behave this way?

  2. Look closely at the following code. Will this program run as the programmer intended?
    /****
     *
     * Program to print the values of different types, with proper spacing.
     * It should print a as "7", b as "15.2594", and c as "something".
     *
     ****/
    
    #include <stdio.h>
    
    int
    main()
    {
      int a = 7;
      double b = 15.2594;
      char * c = "something";
    
      printf ("The value of a is %d.\n", a);
      printf ("The value of b is %.4lf.\n", b);
      printf ("The value of c is %9s.\n", c);
    
      return 0;
    }
    
    • Compile and run the code. Is the output what you expected?

    • In the statement that prints the value of b, edit the %.4lf to be %.2lf. What do you think the output will be? Compile and run the code to check.

    • Now edit the statement that prints the value of b to %.6lf. What do you think will happen? Why? Run the code to check.

    • Given your previous experience, what do you think will happen if you edit the line for the value of c from %9s to %6s. What about editing it to %12s? Run the program. Did your results match your expectations?

    As you may recall, when a number is placed between the '%' character and the variable type, the printf function allocates at least that many spaces for the information. If the information takes that much or more space, then the data is printed normally. However, if the information takes less space, the information is "right-aligned" with the allocated space, with the "extra" spaces left blank. In contrast, when a '.' character (followed by a number) is placed between the '%' and the variable type, only that much space is allocated after the decimal point. For example, if the number is 48.3557, and the print statement indicates that only one value after the decimal should be printed, the printed result will show 48.3 as the variable inserted.

Exercise 4: Practice with printf Spacing

Modify your program from Exercise 1e that takes in an integer, initializes an array of characters with that length, takes in characters until the array is full, and then prints the string. For this exercise, print each character with tabbed spacing. Use only a single printf or fprintf statement.

  1. Now modify your code to use the format %ns, where n is some number, instead of a tab to separate each letter.
  2. List one advantage and one disadvantage of each method of spacing.

Exercise 5: Formatted Binary Conversion Output

In the section on data representation, you learned about the computer's binary representation of decimal numbers. Use what you learned to write a short program that prints the numbers 0 to 32 and their binary representations. Sample output is below:

Conversion Table for Integers and Binary
   Numbers          Binary Representation
      0                    000000
      1                    000001
      2                    000010
      3                    000011
      4                    000100
      5                    000101
      6                    000110
      7                    000111
      8                    001000
      9                    001001
              ...
     28                    011100
     29                    011101
     30                    011110
     31                    011111
     32                    100000

Reminder: Complete Evaluation Form

When you have finished this lab, be sure to fill out its evaluation form in the "Lab Evaluation" section for CSC 161 on Pioneer Web.