CpSc 1111 Lab 4 Formatting and Flow Control Overview By the end of the lab, you will be able to: use fscanf() to accept a character input from the user and print out the ASCII decimal, octal, and hexadecimal values of that character format the above output using flag and width specifications in the fprintf() statement so that the values line up in columns execute a basic block iteratively using loops to produce a rectangular shape using the character entered by the user Background Information The following will review the three different types of loops that you learned about last week in lecture. Also, there is a section about formatting output. Loops Remember lab 1 where you were supposed to print Hello World! 20 times? What if you were supposed to print that message 1000 times? Would you really copy and paste it 1000 times in your program? Sometimes it is necessary to repetitively execute a statement, or block of statements, while some condition remains true, or until some condition becomes false. Because of all the possible formulations of conditions, it is the case that there are multiple correct ways to construct such iterations. And, alas, there are even more incorrect ways to construct them. There are three different iteration constructs in C: 1. while loop 2. do-while loop 3. for loop 1. while Loop The while loop allows us to write a segment of code that repeats while some condition remains true. Structure: // loop index variable used in condition declared and // initialized somewhere above the while loop while (condition) { one-or-more statements; loop_expression; // expression that changes the condition, // updates the loop index variable 1
Important Notes: The statement or statements controlled by the while loop are called the body of the loop and are enclosed by curly braces. It is necessary that the body of the loop modify the value of the condition. Why? Proper use of indentation is critical for human readability. But, indentation is completely irrelevant to the C compiler. Print the integer values between 10 and 1 in decreasing order. (Note: This is not a complete C program; it needs to include stdio.h and it needs a proper main() function header. Also, it is not indented properly see how hard it is to read and make sense of the code?) int value; value = 10; fprintf(stdout, " Table Of Values \n"); while (value > 0) { fprintf (stdout, "%3d\n", value); value = value - 1; In the above code, we only want the heading to be printed one time, so the first fprintf() is placed outside the loop. Example of while loop (with proper formatting and good use of comments): // addition.c // 08/31/15 // Print the sum of positive integers provided by the user. #include <stdio.h> int main(void) { int input; // to hold user input int sum = 0; // sum of all input values // prompt user and get input printf("enter a positive integer, or a negative integer when done: "); scanf("%d", &input); // loop to add each input to sum, and get another integer from user while (input >= 0) { sum = sum + input; printf("enter a positive integer, or a negative integer when done: "); scanf("%d", &input); // display the sum printf("the sum is %d\n", sum); return 0; Notice that we prompt the user for the first input before the loop. Inside the loop, we do the math and prompt the user for the next number. 2
2. do-while Loop The do-while loop allows us to write a segment of code that also repeats while some condition remains true. Structure: // loop index variable used in condition declared and // initialized somewhere above do-while loop do { one-or-more statements; loop_expression; // expression that changes the condition, or updates // the loop index variable while (condition); Important Notes: The above loop is guaranteed to execute the statement(s) at least once. Do you see why? As with the while() loop, it is necessary that the body of the loop modify the value of the condition so that it is not an infinite loop. Don t forget the semi-colon after the while condition. The other loops do not have a semi-colon at the end of the loop. 3. for Loop The third loop structure is the for loop. Structure: // loop index variable declared somewhere above for loop for (init_expression; loop_condition; loop_expression) { one-or-more statements; Important Notes: The statement or statements controlled by the for loop are called the body of the loop and are enclosed in curly braces. The init_expression gives the starting value for the control variable (loop index variable) being used by the loop. The control variable needs to be declared somewhere above the for loop, probably at the top of the program where the other variables are declared. int i; for (i = 0; loop_condition; loop_expression) The loop_condition will be evaluated before each iteration of the loop; if it evaluates to true, an iteration of the loop body will occur; if it evaluates to false, no code inside the body of the loop will execute. int i; for (i = 0; i <= 3; loop_expression) o In this code above, as long as the value of i is less than or equal to 3, the statements inside the body of the loop will be executed. 3
The loop_expression will change the value of the loop control variable so that a stopping point may be reached in the loop_condition. int i; for (i = 0; i <= 3; i++) o In the code above, i will increment by 1 each time immediately after an iteration of the loop, allowing for the loop_condition to eventually evaluate to false (assuming a proper condition exists), thereby ending the loop. (i++ is the same as i = i + 1 and the same as i += 1 and with loops, the same as ++i ) for (value = 10; value > 0; value--) { fprintf(stdout, "%3d\n", value); Note: value-- is the same as value = value 1 Also, the starting value for the control variable called value in this case is 10, and it decrements by 1 after each iteration of the loop. The loop will continue to iterate as long as the value of the control variable is greater than 0. So, how many iterations will occur? Review of scanf() and characters By now, you know to use scanf() or fscanf() to get input from the user. For example, if you were asking the user to enter an integer, and storing their input into a variable called input, your code might look like the following: int input; fprintf(stdout, Enter an integer: ); fscanf(stdin, %d, &input); If the user were to enter a character, your code would change this way: char inputchar; fprintf(stdout, Enter a character: ); fscanf(stdin, %c, &inputchar); Remember that characters are char type, which is really a specialized type of int. If the user entered a lower case t as their character which was stored in the variable called inputchar, to print the value of that variable, you would use %c as the format string, just like above in the fscanf(), such as: fprintf(stdout, %c, inputchar); Which would print the letter t to the screen. If you instead typed the following, what would be printed? fprintf(stdout, %d, inputchar); If you refer to an ASCII table, such as this one: http://www.asciitable.com, you will see that the decimal (integer) value for the lower case t is 116. You will also see that the octal value of that letter is 164, and the hexadecimal value is 74. That same ASCII table is also in section 3.7 of the the Chapter 3 notes posted on Canvas, as well as a direct link on the Chapter 3 page on Canvas. 4
Formatting output On the very first page of the Chapter 3 notes posted on Canvas, section 3.2, you will see that to print an octal value to the screen, you would use %o or %#o in the printf statement. Using the second one: %#o prints a leading 0. int x = 42; fprintf(stdout, %o, x); fprintf(stdout, %#o, x); produces the following output: 52 052 because 42 in decimal has an octal value of 52. Refer to that section of the notes for more information on how to print out the hex values of an integer. You could create a test.c file (not to be handed in) to play around with these different types of formatting to get a feel for how they work. At the bottom of page 6 of the notes, section 3.5, you can also get other hints on how to format output, such as lining up values in columns. You already know that to limit the precision of a floating-point value printed out to the screen to three decimal places, you might do something like the following: fprintf(stdout, %.3f, var1); There are other flags and modifiers that can be included in a print statement to format the output: %[flags][width][.precision][length]type where flags include: - left-justify + generate a plus sign for positive values # put a leading 0 (zero) on an octal value and 0x (zero-x) on a hex value 0 (zero, not the letter O ) pad a number with leading zeros and the width modifier: is the minimum number of characters to generate numbers are padded with leading spaces unless the width has a leading zero flag specifying leading zeros if the number is larger than the number of digits specified, the number will be printed with the wider width For example, using the - as a flag, left justifies the values in a column that is width wide. fprintf(stdout, %-6d%-6d, 12, 43); fprintf(stdout, %-6d%-6d, 324, 72); produces the following output with the values in columns that are 6 characters wide and are left-justified: 12 43 324 72 You can add additional code like the above example into your test.c file to play around with formatting output into columns, left justified or not, using a plus sign for positive values, etc. 5
Lab Assignment Reminder About Formatting and Comments The top of your file should have a header comment, which should contain: o Your name o Course and semester o Lab number o Brief description about what the program does o Any other helpful information that you think would be good to have. Variables should be declared at the top of the main function. Most of the time, you are told that variables should have meaningful names. However, it is acceptable to use i or j or n or some other single letter as a loop index variable name. Always indent your code in a readable way. Some formatting examples may be found here: https://people.cs.clemson.edu/~chochri/assignments/formatting_examples.pdf Don t forget to use the Wall flag when compiling, for example: gcc Wall lab4.c Create a file called lab4.c. In it, provide a C program that will do the following: 1. Prompt the user to enter a character. Note: Use fprintf() and fscanf () functions throughout your program. 2. Show the decimal, octal, and hexadecimal values for that character using the formatting flags and modifiers discussed on the previous page to print the values so that they are lined up in columns, similar to the example outputs below. The first column should be 10 characters wide; the second column 9 characters wide; and the third column 8 characters. 3. Test this much out (compile and run) and make sure it works before continuing on with the next step. 4. Then prompt the user to enter two integers, one for the length and one for the height of a rectangle. 5. Use loops to draw a rectangle made of the character that the user entered, and using the length and height entered by the user. (Don t worry about the difference in spacing of the character horizontally vs vertically. You could add spacing in between the characters horizontally to make the spacing look the same, but it may overcomplicate things for this part of the lab, the main purpose being to get loops to work. If you really wanted to perfect your output with the rectangle, you could work on that on your own later, but it s not required for this lab.) Enter a character: Z SAMPLE OUTPUT #1 Your character was Z which has these numerical values: DECIMAL OCTAL HEX 90 0132 0x5a Now let's draw a rectangle with your character. Enter two integers, one for length, one for height: 6 3 ZZZZZZ Z Z ZZZZZZ 6
SAMPLE OUTPUT #2 Enter a character: % Your character was % which has these numerical values: DECIMAL OCTAL HEX 37 045 0x25 Now let's draw a rectangle with your character. Enter two integers, one for length, one for height: 5 8 %%%%% %%%%% Turn In Work Show your ta that you completed the assignment. Then submit your lab4.c program using the handin page: http://handin.cs.clemson.edu Grading Rubric For this lab, points will be based on the following: Functionality 70 (-5 if warnings when compile) Formatting 10 Use of loops for rectangle 10 Use of fprintf() and fscanf() 5 Printout of decimal, octal and hex values of the character in columns using flags/modifiers in fprintf() 5 (1 st column width of 10; 2 nd column 9; 3 rd column 8) 7