Tuesday, September 06, 2011

Coding Lessons: C and more inputs (Lesson 5)

So in the last lesson we dealt with only integers, in the same way as lesson 2 introduced the idea of variables, and we focused on one type of input (mostly so that I could keep my focus and the lesson wouldn't go on too long).

Now we're going to take a look at all the other types that are available to us.

Other Variables
We did integers pretty much to death in the last lesson, looking at how to declare, then how to read them, how to over flow them.

Remember how I said that the scanf statement looked like the printf statement. and worked in much the same way too?
Well just like the printf statement you can specify the width of the number, you can add modifiers (long, short signed and unsigned) to the type...

For example
%9ld would take an input that was 9 characters in width, and was a long integer.

So lets go over getting variables into a program.
We'll of course start by making a program, (so create a new lesson 5 folder and a new source file etc).

Then start writing the source in the normal way:
#include<stdio.h> int main() {
and declare some variables of different types that we'll be using to store the data entered by users in.
short int whole_number; char character1, character2; float not_whole_number;

Now lets start asking the user of the program to enter data,
Again we'll start by asking the user to enter the first char that we defined:
printf("enter char1:"); scanf("%c", &character1);

Then we'll ask the user to enter that short int:
printf("enter the short int:"); scanf("%hd", &whole_number);
remember we use the modifier h after the % sign to specify that it's a short integer.

Now we'll ask the user to enter the next character, (chracter2):
printf("Enter the char2:"); scanf("%c", &character2);

And finally get them to enter that floating number:
printf("Enter the float:"); scanf("%f", &not_whole_number);

now let's display back to the user the values that they entered:

printf ("the values entered were\r\n"); printf ("char1:%c, shortint:%hd, char2:%c, float:%f",character1, whole_number, character2, not_whole_number);

and finish our main function by closing the curly bracket:
}

The complete code should look like this:
#include<stdio .h>
int main()
{
short int whole_number;  
char character1, character2;  
float not_whole_number;
printf("enter char1:");
scanf("%c", &character1);
printf("enter the short int:");
scanf("%hd", &whole_number);
printf("Enter the char2:");
scanf("%c", &character2);
printf("Enter the float:");  
scanf("%f", &not_whole_number);
printf ("the values entered were\r\n");
printf ("char1:%c, shortint:%hd, char2:%c, float:%f",character1, whole_number, character2, not_whole_number);
}

Now you need to compile your program, and run it to make sure that it works.
D:\coding\lesson5>tcc lesson5.c
 D:\coding\lesson5>lesson5.exe
enter char1:a
enter the short int:1
Enter the char2:
Enter the float:1.2
the values entered were char1:a, shortint:1, char2: , float:1.200000  
D:\coding\lesson5>

Something strange happened there, we were able to enter the first character input, and the integer, but after that we were only able to enter the floating point number, and when displayed the program seemed to put a line break in unexpectedly.

Buffers
What happened there was no mistake, it looks a little weird, but what happened there was that when we entered that that short integer, we entered the number then hit enter.
so what we actually entered was
1\n
Now we told the program to look at the keyboard buffer, and read a short integer from it, so it took the one leaving \n in the keyboard buffer.
then we told the program to look for a char in the keyboard buffer, and it found \n and used that.

So the reason that the program didn't wait for us to enter a value, is because it already found one.
the reason that there is a line break in the output results is because that's what the character is (\n), so as I said, there is no mistake, the program is just doing what it was asked.
So how can we get data into that variable?

well, we can either just fill the keyboard buffer with what we want: (entering all the variables at once) and the scanf statements will just pick out the data that they are interested in.
D:\coding\lesson5>lesson5.exe enter char1:a4b6.7 enter the short int:Enter the char2:Enter the float:the values entered were char1:a, shortint:4, char2:b, float:6.700000

or, we can do it the proper way and flush the input buffer before reading it so that we know that it's empty and only getting what we want.

Flushing buffers

to flush the buffers in a program, (that is erase them all and make them ready to accept new input, we use the function;
flushall();
So all we need to do now is re-visit that code, and flush the buffers before reading inputs.

#include<stdio .h>
 int main()
{
short int whole_number; char character1, character2;
 float not_whole_number;
printf("enter char1:");
flushall();
scanf("%c", &character1); printf("enter the short int:");
flushall();
scanf("%hd", &whole_number); printf("Enter the char2:");
flushall();
scanf("%c", &character2); printf("Enter the float:");
flushall();  
scanf("%f", &not_whole_number);
 printf ("the values entered were\r\n");  
printf ("char1:%c, shortint:%hd, char2:%c, float:%f",character1, whole_number, character2, not_whole_number);
}

Making pretty outputs
Now, I can't help but feel that just putting data out on one line looks a little, well messy, it's nice for computers to read, but I'm not a computer.

So lets have a look at making our data outputting a little neater.

A few lessons ago we introduced the concept of displaying characters with their ASCII number rather than the data.
I put a link to the table found at http://www.asciitable.com/, we looked at how a character could be 97, which was a lower case a, and 98 was a b.

Well, now we're going to start using the characters, 185, 186, 200, 201, 202, 203, 204, 205 and 206... you'll see that these are double line corners, double horizontal lines (like =) double vertical lines, and junctions between these lines.

we'll start by deciding how wide we want our columns to be, I'm choosing 8 character places.

so we'll draw the top of our table:
printf ("the values entered were\r\n");
printf("%c", 201);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 203);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 203);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
 printf("%c\r\n", 187);

(Note that if you were a real sadist, all this could be done on a single line! but I feel that'd be a bit confusing).

Then we'll write out our column headers:
printf("%c", 186);
printf("Char 1 ");
printf("%c", 186);
printf("Shortint");
printf("%c", 186);  
printf("Char 2 ");
printf("%c\r\n", 186);
notice I've used white space to pad out those titles to 8character lengths, (by white space I mean I pressed the space bar three times after writing float, (float has five characters, but to make it up to 8, I added 3 blank characters.)

Then we'll close the table cells,
printf("%c", 204);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 206);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 206);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c\r\n", 185);
and now we'll enter the variables:
printf("%c", 186);
printf("%8c", character1);
printf("%c", 186);
printf("%8hd", whole_number);
printf("%c", 186);  
printf("%8c", character2);
printf("%c\r\n", 186);

Remember how we set the columns to be 8 characters wide, well, that's meant that we have to either pad out, or restrict variables.

So we've used %8c, to make the characters take up 8 spaces, we've made the short in take up 8 spaces by writing %8hd.

Then we close our table:
printf("%c", 200);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 202);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);  
printf("%c", 202);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c\r\n", 188);

So the complete code for that bit is:

#include<stdio.h>
int main()  
{
short int whole_number; char character1, character2;
printf("enter char1:");  
flushall();  
scanf("%c", &character1);  
printf("enter the short int:");
flushall();
scanf("%hd", &whole_number);  
printf("Enter the char2:");
flushall();  
scanf("%c", &character2);
printf ("the values entered were\r\n");
printf("%c", 201);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 203);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 203);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);  
printf("%c\r\n", 187);  
printf("%c", 186);
 printf("Char 1 ");
printf("%c", 186);
printf("Shortint");
printf("%c", 186);  
printf("Char 2 ");  
printf("%c\r\n", 186);
printf("%c", 204);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 206);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 206);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c\r\n", 185);  
printf("%c", 186);  
printf("%8c", character1);  
printf("%c", 186);  
printf("%8hd", whole_number);
printf("%c", 186);  
printf("%8c", character2);
printf("%c\r\n", 186);  
printf("%c", 200);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 202);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 202);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c\r\n", 188);
 }


Yes, I have deliberately taken out the float type of variable.

Compile this and run it, and you should see the following:
D:\coding\lesson5>tcc lesson5.c
D:\coding\lesson5>lesson5.exe
enter char1:1 
enter the short int:s
Enter the char2:1
the values entered were 
╔════════╦════════╦════════╗
║Char 1  ║Shortint║Char 2  ║
╠════════╬════════╬════════╣
║       1║      64║       1║
╚════════╩════════╩════════╝  

No comments: