C - From The Top (part 4 - Strings 'n' Stuff)

OK, here's the answer to the poser left at the end of the third exciting instalment...

#include <stdio.h>
int main(void)
{
 int no1,no2,doer;
 do
 {
  printf("Please select : \n\n");
  printf("1. Add\n2. Subtract\n3.Multiply\n4. Divide\n");
  printf("5. Modulus\n6. Quit    ");
  do
  {scanf("%d" ,&doer);
  }
  while (doer<1 || doer>6);
  if (doer==6) break;
  printf("Please enter your first number : ");
  scanf("%d",&no1);
  printf("Please enter your second number : ");
  scanf("%d",&no2);
  printf("\n");
  switch (doer)
  {1 : printf("%d + %d = %d\n",no1,no2,no1+no2);
            break;
   case 2 : printf("%d - %d = %d\n",no1,no2,no1-no2);
            break;
   case 3 : printf("%d * %d = %d\n",no1,no2,no1*no2);
            break;
   case 4 : no2=0 ? printf("%d / %d =%d\n",no1,no2,no1/no2) :
            printf("Your second number is a zero\n");
            break;
   case 5 : no2=0 ? printf("Your second number is a zero\n") :
            printf("%d %% %d = %d\n",no1,no2,no1%no2);
            break;
  }
 }
 while (doer!=6);
 return 0;
}

If you think about it, this could be the start of a nice simple calculator...

Up to now, we have only had to deal with one header file (a header file has the extension .h on it and contains all the extra bits that the main code needs - it's a really useful method of including variables or extra functions which can be called on by any part of the source code file(s)) - that is <stdio.h>, the standard input/output header. To handle strings, both the <stdio.h> and <string.h> header files need to be used.

String.h provides a number of functions which can be called upon.

The four main functions provided are:

strcpy (to, from)
strcat (to, from)
strcmp (string_1, string_2)
strlen (string)

That's nice, but what do they do?

strcpy = string copy from one string to another (another way is to say a$=b$).

strcat = string concatenate. Concatenation is when you place part of one string into another. This is a very powerful function in its own right. For instance, say you had (in Basic) the following two lines:

a$="I'm Paul Johnson"
b$="Hello, "

to join them together you would need b$+=a$. In C, you simply need strcat(b$,a$) - well, not quite; I'm still using the $ variable which doesn't exist in C, but suits for this example.

strcmp = string compare. If the two strings are the same, the result is false, otherwise it is true.
This is the same as using IF a$=b$
strlen = string length. It's the same as LEN(a$).

When using strings in C, you must remember to reserve the space first. To do this use

char <variable> [size_reqd];

You also have to remember to make size_reqd large enough as there is no bounds checking of the input or processed size. Failure to do so will result in your program crashing.

A second point is that, when <return> is pressed, this is also stored, so having a 20-character input needs 21 characters to include the return code.

Let's have some examples...

You have already seen that there are two methods of getting text into a variable, namely gets() and scanf("%s"). There is a third called getchar(). Here comes a problem though.

getchar() is supposed to read one character - however, RISC OS machines have a buffered input
system. The upshot is that getchar() will return everything until <return> is pressed. There
is a port of the Microsoft conio.h library which includes the function getche() which does only
read one character. This library is not part of ANSI C, so I'm only going to mention it here in
passing.

To get round this problem, include a dummy getchar() or gets() command (basically, repeat the input line). This is not the most efficient method of obtaining a single character, but until we reach using the SWIs (which isn't until much later - no running before we can walk now!), it will have to do.

All right, we've defined a character array variable (called string) which will be more than long enough for our needs.

Using strcpy

strcpy (string,"Hello there, Eccles");
printf("%s",string);

This has placed the text Hello there, Eccles into our variable, string.

Using strcat

strcat (string,", my good man.");
printf("%s",string);

will have added , my good man. to the original text in our variable string. The full output text after strcat will be Hello there Eccles, my good man.

Using strlen

printf("%d",strlen(string));

this will say 32.

However, if the second part had been an input, you would assume that there the strlen(string) would return 33 after the concatenation of the two. It will still return 32. The reason is that the strlen function ignores the return key when calculating the length of the string.

Using strcmp

If string 1 < string 2, the result is -1.

If string 1 > string 2, the result is 1.

If string 1 = string 2, the result is 0.

The strings are compared alphabetically, so if string 1 was "abcd1efg" and string 2 was "abcd2efg", then string 1 < string 2 (1 is less than 2 alphabetically and also is less than 2 in the ASCII character set, which is more to the point!).

strcmp("abcd1","abcd2")=-1
strcmp("abcd2","abcd1")=1
strcmp("abcdefg","abcdefg")=0

The values inside the quotes can be substituted for the contents of a variable.

strcmp(string,"Fred")=1

Remember, string contains a complete sentence so will be larger than the comparison string.

In the next instalment, I'll deal with pointers and pointers to pointers. These can be quite tricky...

This month's puzzle

Last time, you created a program which would do some basic maths for you by the use of a numerical menu.

Adapt this program so that you can enter "Add" or "add" etc, for the various functions within the program. To exit, type QUIT (in caps). One thing to remember, unlike with numbers, you cannot use the switch case structure unless you have something like:

if ((!strcmp(command,"Add")) || (!strcmp(command,"add"))) dowhat=1;

where dowhat is to be used in the switch command.

You must still keep the same error checking for division and modulus calculations.


Source: Archive Magazine 13.4
Publication: Archive Magazine
Contributor: Paul Johnson