DOC

Introduction to C - Session 6

By Brent Burns,2014-05-07 15:35
8 views 0
Introduction to C - Session 6

Session 6 Conversions & Useful Stuff

In this session we will be taking a look at how we go about performing conversions

between different types of variables in C (which we have taken a brief look at already by

looking at the sprintf and sscanf functions). We will also take a look at the concept of type-casting, which also relates to conversions. We'll be taking a look at some of the more

useful mathematical functions, including a second look at random numbers.

We shall be taking a final look at the use of the printf and scanf functions, and their

string counterparts.

Finally, you will be given a "mock" examination to look at and attempt between now

and the next session, to give you a flavour of what we are aiming to achieve for the

examination, and also in order to gauge your own progress.

Type-Casting (Coercion)

You can force C to convert between different types. For example, in order to allow a

floating-point (i.e. number, possibly with a fractional amount) to be stored into an integer

variable, we need to lose the fractional amount. This would not normally be allowed, as

you are losing information by doing this. However, you can force (or coerce) the C

Compiler to do this by placing the type that you wish to convert to in brackets before the

number of formulae that you wish to convert from. E.g.

float f=3.57; int i=(int)f;

will store the value 3 in the variable i having converted it from the floating-point type given by variable f.

Another unexpected problem you can find is when you divide two integer variable

together, and wish to store the result in a floating point number (it could have a fractional

part, after all), then the C compiler will divide the two integer numbers by each other, and

to produce an integer result, will remove the decimal part. The integer value will then get

stored in the floating point variable.

Try the following program, and you will see the problem:-

#include <stdio.h>

#include <conio.h>

void main() {

int i1=7, i2=3; float f=i1/i2;

printf("%d/%d=%6.2f\n",i1,i2,f); getch();

}

This produces the following result (press a key to finish):-

INTRODUCTION TO C / UNIT 6 Author: Simon Huggins Page 1

To get the correct result, we need to convert at least one of the values being divided

to a floating point number. Just to be safe, we'll convert both values, by prefixing them with

the (float) casting operator: -

The program becomes: -

#include <stdio.h>

#include <conio.h>

void main() {

int i1=7, i2=3; float f=(float)i1/(float)i2;

printf("%d/%d=%6.2f\n",i1,i2,f); getch();

}

which gives us the following result: -

i.e. two and a third, which is what we would expect.

Converting to and from Strings

Converting data to and from string (text) data can be done in a number of ways. As

strings are not built into the C language as a feature, we will need to make use of some

standard libraries by using the #include directive and use the functions held in these

libraries.

Here's a list of methods for converting to and from strings:-

from type to type function library string float float f=atof("1.23"); math.h string integer int i = atoi("123"); math.h string float sscanf("1.23","%f",&f); stdio.h string integer sscanf("123","%d",&i); stdio.h float string sprintf(str,"%f",&f); stdio.h integer string sprintf(str,"%d,&i); stdio.h

In general, you will find that the sprintf and sscanf functions are most useful, and

can be tailored to accept input/output in a variety of forms. See the example in session 2

on using scanf to read a date format string into three variables.

printf, scanf, sprintf & sscanf

printf is used for writing variables and text in combination to the console (screen).

sprintf writes the output to a string variable instead of the screen.

Similarly, scanf is the opposite function, which takes input from the keyboard,

expected to be a particular combination of text and values, and extracts those values into

variables.

Try typing in the following listing, which takes your forename and surname

(separated by a space) and separates them into two separate strings. It then takes your

INTRODUCTION TO C / UNIT 6 Author: Simon Huggins Page 2

age in the form (nnn years) and stores it to an integer variable, and then combines the

data into a single string that is displayed on the screen.

#include <stdio.h>

#include <conio.h>

void main() {

char forename[30],surname[30]; int years;

printf("What is your name (forename then surname)? ");

scanf("%s %s",forename,surname);

printf("Name is: %s, %s\n\n",surname,forename);

printf("What is your age (n years)? ");

scanf("%d years",&years);

printf("Welcome %s, the %d year old member of the %s family.",

forename,years,surname);

getch();

}

Notice that the forename and surname are read in as two separate strings,

separated by a space. It is then shown on the screen in reverse order, separated by a

comma.

If you try typing out the number of years without typing out the word years afterwards,

then the program will not continue until you have typed years. That is because the second

scanf statement waits for an integer number followed by a space followed by the word

years to be typed before it is satisfied. The integer number (%d) part is then placed in the

&years variable.

Finally, all of this data is put together and displayed on the console in a single printf

statement.

The following statement will take a date previously entered into a string, and convert

it to three integer values for day, month and year: -

char str[11]; int day,month,year;

strcpy(str,"05-06-2002");

sscanf(str,"%d-%d-%d",&day,&month,&year);

Remember that any parameters passed by reference to the sscanf procedure need

to have an & put before them, except str which is a string variable, and implicitly passes the address of the character array.

...And if you wanted to do the reverse, and put the day, month and year into the

string variable, then you might do this: -

char str[11]; int day,month,year;

day=5; month=6; year=2002;

sprintf(str,"%02d-%02d-%4d",day,month,year);

INTRODUCTION TO C / UNIT 6 Author: Simon Huggins Page 3

Format Specifiers

Format specifiers are the parts of the string template that start with a percentage (%)

symbol and end with a character that specifies the type of string that is to be inserted at

that point in the string. The most common characters to use are: s for string (or array of char), c for character, d for integer and f for float.

You can put a number between the % and the letter to specify the length of the field. In the

example given above, the day is padded to 2 characters, the month to 2 characters, and

the year to 4 characters. By default, the padding character is a space. However, if you

prefix the width number with a zero (0), then the padding will be with zero characters.

Finally, if you specify a decimal with floating points (e.g. %5.2f) then the format will be 5 characters wide, with 2 decimal places, giving 2 digits before the decimal point (e.g. 12.34

is five characters wide, with two decimal places, which leaves two digits before the

decimal point).

Exercise 1

Write a program that reads in a time in the format hh:mm:ss where hh is the number of hours, mm is the number of minutes, and ss the number of seconds.

Work out the number of seconds elapsed since midnight the formula is (minutes*60)+(hours*60*60)+seconds.

Exercise 2

Write a program that reads ten floats into an array called float_array. Find the total, average, smallest and largest numbers, and display each results with a width of 10 and to

four decimal places.

If you can, split each of the tasks of the program into separate functions one to display the title, one to read the values, one to find the statistics, and one to display all of

the values (formatted) again, followed by the statistics. Make your variables global instead

of passing them as parameters. This will make the program much easier to write.

Math functions

There are various mathematical functions defined in the standard C library stdlib.h and math.h

function library Description

int i=abs(-123); stdlib.h Returns the absolute value of an integer number

i.e. the positive value. Thus, abs(123) returns 123,

and abs(-123) also returns 123. int i=rand()%100; stdlib.h Returns a pseudo-random number from 0 to 99. randomize(); stdlib.h Randomizes the production of random numbers.

Always include this line at least at the beginning of

any program that uses random numbers. double d = pow(5.0,3.0); math.h Raises the first parameter to the power of the 3second parameter. The example given is 5 which is

5 x 5 x 5 = 125.0. Note that the parameters can be

fractions.

double s = sqrt(25.0); math.h Find the square root of the given value and return a

double float value. In this example, the square root

INTRODUCTION TO C / UNIT 6 Author: Simon Huggins Page 4

1/2. of 25 is 5 (i.e. 5 x 5 = 25 this is the same as 5

For example, to generate 10 random squared numbers: -

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include <conio.h>

main() {

for(int i=1; i<=10; i++) {

int rno = rand()%100;

printf("Number %02d: Square of %2d is %5d\n",

i,rno,(int)pow(rno,2.0));

getch();

}

}

Note that you need to press a key after each displayed number to display the next of

the set of ten.

Exercise 3

Write a program that works out the length of the long side of a triangle (called the

hypotenuse) given the length of the other two sides (called the opposite and adjacent

sides).

Store the three values as float values (float type) and ask the user to input the two values (using the scanf function and the %f specifier).

Work out the value of the hypotenuse as being the square of the adjacent side plus

the square of the opposite side, all square-rooted. i.e.

hypotenuse = sqrt ( pow(opposite,2) + pow(adjacent,2) );

Display the values of opposite, adjacent and hypotenuse on three separate, aligned

(i.e. lined up) lines, with the values displayed with a width of 10 and with 3 decimal places.

After displaying the result, ask the user if he or she wishes to work out another value,

and loop back to the beginning if the user presses the Y or y key, otherwise exit the

program.

Sample output might be as follows:-

INTRODUCTION TO C / UNIT 6 Author: Simon Huggins Page 5

Example Exam

The following is a sample exam question to take away with you to complete for the next session.

9531 INTRODUCTORY COMPUTER PROGRAMMING: STRUCTURED ASSIGNMENT

Topic Games and Quizzes

Title of this Assignment Bombs

Introduction

The game of Bomb is a one-player game on a hidden grid.

Assignment Specification

Devise a program that will play the game "Bombs", with a single player.

The game should be played on a grid that is 10x10 in size, using 1 to 10 down and A to J

across to identify each square in the grid.

The computer places ten bombs randomly in the grid, but which are not shown on the

screen.

The grid is then shown on the screen. The grid should display 1 to 10 down the left hand

side of the grid and A to J across the top.

The player chooses an option from one of the following choices: R for reveal, M for Mark,

U for Unmark or X to exit.

The player types out a grid reference (e.g. A1 gives the top-left grid position, J10 gives the bottom-right). This is used to identify a square on the grid. If anything outside this range is typed, then the player is prompted to choose one of the choices (R/M/U/X) again.

If R was chosen, then if the square contained a bomb, the player is told GAME OVER,

and after pressing a key, the program exits. If the square contained nothing, then the eight

squares surrounding that square are checked. If any of them contain a bomb, they should

be counted, and the number of bombs surrounding the square should be placed in the

revealed square.

If M was chosen, the square is marked with an X. If U was chosen, the square is marked

with an space.

If X was chosen, then the program exits, after the user is prompted about whether they

are sure they want to quit.

Check all squares. If all squares have been revealed or marked (i.e. not a space), and all

marked squares have a bomb underneath them, then display GAME OVER. WELL DONE.

and after the user presses a key, end the program.

INTRODUCTION TO C / UNIT 6 Author: Simon Huggins Page 6

Otherwise, loop back to clear the screen, re-display the board, and ask what the user

wants to do next.

It is recommended that you use two arrays, one for the location of the bombs, one to show

the user marks / revealed squares. For example, a square marked with a digit as a

character (1 to 8) would show a revealed square with the number of unrevealed bombs

next to it. An X would show a marked square. A space would show an unrevealed square.

Procedure

a) Describe briefly in writing for a possible user

i) The purpose of your program

ii) The limitations of your program

b) Construct (on paper) a screen layout indicating what will appear on the screen

prompts, input, output with annotations, any other messages.

c) Describe (on paper) the main stages of the program - by means of a flowchart or an

alternative technique.

d) Produce a listing of the program. This should have adequate comment lines and

should demonstrate to the examiner that the program solves the problem set.

e) Include in the program statements to display adequate instruction to the user of the

program e.g. prompts for data entry and appropriate error messages for invalid input.

f) Key in and run the program, producing and using simple test data if necessary. Check

that the program's output agrees with the expected results and correct any errors.

g) Use appropriate language facilities.

Hint Two-Dimensional Arrays

We have talked so far about single-dimension arrays e.g.

int i[3]; i[0]=1; i[1]=2; i[2]=i[0]+i[1];

which leaves us with i[2] containing the value of 3.

However, we can reproduce a grid, which is effectively an array of an array. If you

take a row on our grid as an array of ten characters (char grid_row[10]) then the whole

grid can be taken as an array of rows (char grid[10][10]) which gives us 10x10 characters.

To access each element in the two-dimensional array, refer to the grid position as each

dimension's position (from 0 to 9) in separate square brackets. E.g.

grid[0][0] grid[0][9]

grid[4][4]

grid[9][0] grid[9][9]

INTRODUCTION TO C / UNIT 6 Author: Simon Huggins Page 7

Exercise Results

These are some sample results to the exercises given earlier in the session: -

Exercise 1

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

void main() {

int hours,minutes,seconds;

scanf("%d:%d:%d",&hours,&minutes,&seconds);

printf("Second since midnight: %d\n",

(minutes*60)+(hours*60*60)+seconds);

getch();

}

Exercise 2

/*

** Session 6, Exercise 2

** Written by Simon Huggins

*/

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

/* Function Prototypes */

void show_title();

void find_stats();

void show_stats();

/* Global Variables */

float float_array[10], total, average, smallest, largest;

/* Main Function */

void main() {

show_title();

find_stats();

show_stats();

printf("\n\nPress a key... "); getch(); }

/* Display the title banner */

void show_title() {

printf("Statistics Program\n");

printf("------------------\n\n"); }

INTRODUCTION TO C / UNIT 6 Author: Simon Huggins Page 8

/* Read data into array from user */

for(int i=0; i<10; i++) {

printf("Enter value #%2d: ",i+1);

/* remember arrays do not need to be

prefixed with an & symbol */

scanf("%f",&float_array[i]);

}

}

/* Find statistics */

void find_stats() {

total=0; smallest=99999; largest=-99999;

for (int i=0; i<10; i++) {

total = total + float_array[i];

if (float_array[i] < smallest) smallest = float_array[i];

if (float_array[i] > largest ) largest = float_array[i];

}

average = total / 10.0;

}

/* Show statistics */

void show_stats() {

clrscr();

printf("Results are as follows: -\n\n");

for (int i=0; i<10; i++)

printf("No.%2d is %10.4f\n",i,float_array[i]+1);

printf("\n\nStats are:-\nCount is 10\n");

printf(" Total is %10.4f\n",total);

printf(" Average is %10.4f\n",average);

printf("Smallest is %10.4f\n",smallest);

printf(" Largest is %10.4f\n",largest); }

Exercise 3

/*

** Session 6, Exercise 3

** Written by Simon Huggins

*/

#include <stdio.h>

#include <conio.h>

#include <math.h>

main() {

printf("Hypotenuse Calculator\n");

printf("---------------------\n\n");

printf("Enter Opposite: "); scanf("%f", &opposite);

hypotenuse = sqrt ( pow(opposite,2) + pow(adjacent,2) );

printf("\n\n Opposite is: %10.3f\n", opposite);