Basic arithmetic, input/output, conditionals and loops


Your assignment must be submitted electronically via Sakai by 11:55 pm on Friday, January 24, 2020 (submission instructions at the bottom).


Exercise 0

Prior to beginning this tutorial, carefully review the description of the following input/output functions:

Relevant readings are:

You should also use the man command to read the online manual pages for each of these functions (use the spacebar to scroll to the next page, 'b' to the previous page, up/down arrows to scroll a line, and 'q' to quit).

% man scanf

Make sure you understand the format strings used by scanf() and printf() to specify the format of the input/output, especially reading/writing characters, strings, integers, and floats. Make sure you understand how the width (i.e., number of characters used) is specified in a format string, and also how left- vs. right-justification is specified.

A good summary of the formatting specifiers for scanf() and printf() is available here: http://www.cplusplus.com/reference/cstdio/scanf/ and http://www.cplusplus.com/reference/cstdio/printf/.

In the exercises below, you will only need the scanf and printf functions, but you will use the others listed above in future assignments.


Very Important Tip: When reading integers and floating-point numbers using scanf, you must use the ampersand operator ('&') before the variable that needs to be read. Thus, to read a decimal integer n, you would write:

scanf("%d", &n);

And not:

scanf("%d", n); // <==== WRONG!

The reason is that "&n" indicates "the address of n", which tells scanf where to store the number read. In contrast, simply writing "n" would represent the current value of n, which does not help scanf determine where to put the number just read. This point will be fully explained in class in a few weeks when we discuss pointers in C.

Another Important Tip: When printing using printf, you need to specify within the format string all the white spaces you would like printed. For example, printf("%d  %f\n\n", 1, 2.1); prints the integer 1 and float 2.1 separated by two spaces, followed by two newlines. However, when reading the same, you will use scanf("%d%f", &i, &f);, without specifying any white spaces between the integer and the float being read. This is because the scanf function, when reading numbers, skips over all white space before the start of the number, exactly as would be expected of such a routine. So, it would correctly read i and f regardless of whether they were separated by one space, two spaces, three tabs, five newlines, etc. However, if you were to write scanf("%d  %f\n\n", &i, &f);, then the function will expect (at least) two spaces between the numbers, and two newlines afterward.

So, in summary, avoid spaces in the format string for scanf, but provide exact spacing/newlines in the format string for printf.


Note

For the exercises below, create a folder lab2 inside the comp411lab folder that you already have under your home directory on the class server (comp411-1sp20.cs.unc.edu). For the exercises below, you will code your C programs in the files ex1.c, ex2.c, ex3.c, ex4.c and ex5.c, respectively. Sample input and output files are provided in the folder /home/montek/comp411/samples/lab2.


Exercise 1

This is an exercise in basic C programming involving the following concepts: a loop (for / while), conditionals (if-else), and input/output (scanf/printf).

Write a program that does the following: It prompts the user with "Enter a number from 1 to 20:\n" (note the newline after the colon), and reads the user's response. If the user's response was, say, 10, the program then prints a short message followed by the first 10 ordinal numbers (see this article), one per line, and then terminates. If the user enters a number that is outside of the 1..20 range, the program should print the error message "Number is not in the range from 1 to 20\n" (note the newline at the end), and terminate.

The file with your C program should be called ex1.c, and the compiled version called ex1. Compile the C program using the C compiler (cc or gcc), and test it with a few different inputs. You can find sample test input and output files as described above. Below is one execution scenario (program output is blue and input is red):

Enter a number from 1 to 20:

7

Here are the first 7 ordinal numbers:

1st

2nd

3rd

4th

5th

6th

7th

Here's another scenario:

Enter a number from 1 to 20:

22

Number is not in the range from 1 to 20

Assume that the ordinal numbers from 4 to 20 are all spelled with a th, i.e., 4th, 5th, ... 20th.


Exercise 2

This is an exercise that introduces the following concepts: floating-point numbers (doubles), and arithmetic and input/output of those numbers.

Write a program that requests 10 double-precision floating-point numbers (data type double), and prints their sum, minimum, maximum, and product to 5 decimal places. Specifically, the program should prompt the user with this message "Enter 10 floating-point numbers:\n" (note the newline after the colon). It should print the sum, minimum, maximum and product formatted exactly as shown (to 5 digits after the decimal point):

Enter 10 floating-point numbers:

1.45 -2e2 -2e-2 14 -10.0 0.01 -0.02 20 -3e1 +4e+0

Sum is -200.58000

Min is -200.00000

Max is 20.00000

Product is -389.76000

Tip: There is no need to use arrays for this exercise. You can calculate/update all four of the output values each time a new number is read from the input. In particular, the first value read becomes the initial sum, min, max and product. Then, every subsequent value read simply updates these four quantities. To print to 5 decimal places, carefully select the format string for printf(), specifically, the specifier, width and precision, after studying the tables given at http://www.cplusplus.com/reference/cstdio/printf/.

Name the file with the C program ex2.c. Compile it, save the executable as ex2, and test it on the sample input and output files provided.


Exercise 3

This is an exercise that introduces reading and writing octal and hexadecimal integers, as well as formatting spacing/padding. In this context, please note that decimal means a number written in base 10; it does not mean that it has a decimal point and a fractional part! Likewise, octal is base 8, and hexadecimal (or "hex") is base 16.

Write a program that requests six integers ("Enter six integers:\n") (note newline after colon), reads all of them, then prints all of them in the following format: (i) first print a header line as shown in the example below; then (ii) two integers per line, with each integer right-justified in a field of 10 characters, separated by two blank spaces. Each of the integers supplied could be in either decimal, octal or hexadecimal format, and your program should read it correctly. For output, each integer should be printed in decimal format.

For example, if the numbers input are 1, 010, 0x20, 25, 1000, -200, then the output should be exactly as follows:

Enter six integers:

1 010 0x20 25 1000 -200

1234567890bb1234567890

1 8

32 25

1000 -200

Note: All numbers that start with a '0' are assumed to be octal, i.e., number in base 8 (Wikipedia article). Thus, "010" in octal is the number 0 + 8*1 = 8 in decimal. Similarly, numbers that start with "0x" are assumed to be hexadecimal, i.e., number in base 16 (Wikipedia article). Thus, "0x20" in hexadecimal is the number 0 + 2*16 = 32 in decimal.

Name the file with the C program ex3.c. Compile it to ex3 and test it on the sample input and output files provided.

Tip 1: Carefully study the format specifiers (%i, %d, %u, %o, %x) for scanf() from the reference provided above (http://www.cplusplus.com/reference/cstdio/scanf/).

Tip 2: Carefully study the width specifier for printf() from the reference provided above (http://www.cplusplus.com/reference/cstdio/printf/). There is an example on that page showing how to print a number into a field of 10 characters, preceded by blanks.


Exercise 4

Now redo Exercise 3 so that all integers in the input are strictly interpreted as decimal numbers, even if they start with a leading '0', i.e., the number "010" is the decimal number 10, not the octal form of 8. (The input will not contain any hex numbers starting with '0x'.) Tip: Carefully choose the format specifier (%i, %d, %u, %o, %x) for scanf().

For example, if the numbers input are 1, 010, 00020, 25, 1000, -200, then the output should be exactly as follows:

Enter six integers:

1 010 00020 25 1000 -200

1234567890bb1234567890

1 10

20 25

1000 -200

Name the file with the C program ex4.c. Compile it to ex4 and test it on the sample input and output files provided.


Exercise 5

This is an exercise in nested loops and printing characters.

Write a program that repeatedly reads two integers in decimal format, the first being the width (i.e., number of columns) and the second being the height (i.e., number of rows) of a rectangle. The program prints the rectangle using the characters '+' for each corner and '-' or '|' for each line, and '~' for the interior. The numbers given will all be positive and non-zero and less than 100, except that to end the program, a single 0 is provided for the width (and the program immediately terminates without requiring a height to be entered).

For example, the following is one execution scenario:

Please enter width and height:

5

3

+---+

|~~~|

+---+

Please enter width and height:

6

2

+----+

+----+

Please enter width and height:

2

2

++

++

Please enter width and height:

4

1

+--+

Please enter width and height:

1

1

+

Please enter width and height:

0

End

First test your program by running it through the execution scenario above, and make sure it produces exactly the same output. Name the file with the C program ex5.c. Compile it to ex5 and test it on the sample input and output files provided.


Testing

Sample Inputs and Outputs

Sample inputs and corresponding outputs are provided under /home/montek/comp411/samples/lab2. You should try running your program on the sample input files provided, and make sure the program's output is identical to that in the sample output files.

First, copy all the sample input and output files to your lab2 folder:

% cd ~/comp411lab/lab2
% cp /home/montek/comp411/samples/lab2/* .

(Note the dot at the end of the cp command above.)

To see what these files contain, you can use any of these methods:

Compiling your source code

Use the following commands to compile your C programs (e.g., ex1.c) and create the executables (e.g., ex1):

% gcc ex1.c -o ex1
% gcc ex2.c -o ex2

... and so on.

Running your executable

First, try to run your executable (% ./ex1), and provide it input from the terminal and observe the output. If everything looks good, you can use the following commands to run with our sample inputs. These commands send the output of your program directly to the terminal.

% ./ex1 < ex1in1
% ./ex1 < ex1in2

... and so on.

Now, we will capture the program output into files so we can carefully examine them and compare against the sample outputs provided:

% ./ex1 < ex1in1 > ex1result1
% ./ex1 < ex1in2 > ex1result2

... and so on. Repeat for each sample input file, and repeat for each exercise.

Check the output

You can examine your program output captured in the *result* files by using cat, less or pico, as explained above:

% cat ex1result1

% less ex1result1

% pico ex1result1

Compare your output with the sample output files provided (ex1out1, etc.) to be sure they match exactly.

Using diff

diff is a very powerful utility for comparing the contents of files, and can be used with several different options:

Use the diff command to determine any differences between your program's output (which you redirected into the file ex1result1) and the correct output provided to you (in the file ex1out1). Watch out for extra spaces at end of lines, etc.!

For example:

% diff -qs ex1result1 ex1out1

... and so on. Repeat for each sample input file, and repeat for each exercise.

Before submitting your work, be sure that each of your compiled programs runs correctly on all of the sample inputs provided exactly, i.e., diff reports no differences at all. You may receive zero credit if your program's output does not exactly match the sample outputs provided.

If diff produces errors, please manually inspect your output and the provided output to see what is different. You can use cat or pico to see the contents of the files.

Using hexdump

If the differences are due to white space errors only, it is sometimes hard to find the extra spaces, especially if they are at the end of a line. For that purpose, use hexdump -c filename to dump the contents of the file onto the terminal; it will show the ASCII codes of each character, and make it easy to see trailing white space at the end of lines:

% hexdump -c ex1result1

% hexdump -c ex1out1

Final check before submitting

You can also check your entire Lab 2 by running the self-check script:

% cd ~/comp411lab/lab2
% selfchecklab2

Terminating a hung program

If your program seems to be hung, it is likely either because you have an infinite loop or because it is still expecting an input. In most cases, you can terminate (i.e., kill) the program by hitting Control-C on your keyboard.

Exiting your login session on the server

When you are all done working on the server, you can exit your session by hitting Control-D on your keyboard, or typing "exit" on the command prompt.


Due Date and Submission Procedure

Due Date: 11:55pm on Friday, January 24. You will submit your work on Exercises 1-5. Specifically, only submit the files ex1.c, ex2.c, ex3.c, ex4.c and ex5.c.

How to submit: First transfer your work back to your laptop by either using WinSCP (for Windows), or Cyberduck/FileZilla/Macfusion or terminal/shell (for Mac/Linux), as explained in Lab 1. Next, log in to Sakai in a browser window, and look for the lab under "Assignments" in the left panel. Attach the requested files and submit.

Resubmissions: You are allowed to submit a lab assignment as many times as you would like to, but only the latest submission will be considered for grading.

In case of any problems, please contact the instructor or the TAs.


Written: 6 September 2017, Montek Singh, montek@cs.unc.edu
Revised: 18 January 2018, Don Porter, porter@cs.unc.edu and Montek Singh, montek@cs.unc.edu
Revised: 31 August 2018, Montek Singh, montek@cs.unc.edu
Revised: 30 August 2019, Montek Singh, montek@cs.unc.edu
Revised: 16 January 2020, Montek Singh, montek@cs.unc.edu