CPS 125 

				Alexander Ferworn

					Week 8 

			Strings and Multidimensional Arrays

What we will cover this week

o Strings
o Multidimesional Arrays

Strings
--------
o In C, a string is an array of characters terminated 
	with a null character.
o The null character is \0 (back-slash zero).
o A string constant (or literal) is any series of 
	characters enclosed in double quotes.
o Each character in a string takes up one byte.
o The compiler automatically puts the null character 
	on the end of the characters for you
o Null characters are treated as false (zero) in expressions.

Initializing Strings
---------------------
Example

	char str[]="some text";

o Compiler would assign str[] to be one element larger than 
	the string literal.
o This is the same as;

	char str[10]="some text";

o You must declare enough space to hold the null character.

o You can also do it with a string pointer;

	char *ptr = "more text";

Problems you will face
------------------------
/* a problematic example */
/* note a string is not te same as a character */

void main()
{
	char array[10];
	char *ptr1 = "10 spaces";
	char *ptr2;

	array = "not ok"; /* cannot assign to an address */
	array[5] = 'A';	/* OK */
	ptr1[5] = 'B';	/* OK */
	*ptr2 = "not ok"; /* type mismatch */
	ptr2 = "ok"; /* ptr2 now points to ok */
	*ptr2 = 'a'; /* ok */
	ptr2 = 'a'; /* not ok */
	*ptr2 = "a"; /* nope a is a string */
}

Reading and Writing Strings
----------------------------
o To read and write strings use the %s format specifier

Example

/* read a string into the char array str[] and output it*/

...
char str[80];
scanf("%s",str);
printf("%s",str);
...

The String Length Function
---------------------------
o There is no magic in a string...it's just an array
o Here is a function to return the length of a string

int strlen(char str[])
{	
	int j=0;
	while(str[j]) j++;
	return j;
}

/* slightly different */

int strlen(char str[])
{
	int j;
	for(j=0;str[j];j++);
	return j
}

/* a pointer version */

int strlen(char *str)
{
	int j;
	for(j=0;*str++;j++);
	return j;
}

o *str++ both * and ++ have the same precedence so they are right to left associative

The String Copy Function
--------------------------
o To copy a string you must move one element of the array at a time.

void strcpy(char s1[],char s2[])
{
	int j;
	for(j=0;s1[j];j++)
		s2[j] = s1[j];
	s2[++j] = '\0';	/* ++j evaluates first then the address of s2 is determined */
}

/* using pointers */

void strcpy(char *s1, char *s2)
{
	int j;
	for(j=0; *(s1+j); j++)
		*(s2+i) = *(s1+j);
	s2[++j] = '\0';
}

/* the screamer but hard to understand code */

void strcpy(char *s1, char *s2)
{
	while(*s2++ = *s1++);
}

Some More Useful String Functions
----------------------------------
o strcat(s1,s2) -- appends a copy of string s2 onto the end of string s1

/*EXAMPLE strcat() use */
#include <stdio.h>
#include <string.h>

void main()
{
	char s1[25] = "hello ";
	char *s2 = "world";
	printf( "Before strcat(): s1 = \"%s\"\n", s1 );
	strcat( s1, s2 );
	printf( "After strcat():  s1 = \"%s\"\n", s1 );
}

produces

Before strcat(): s1 = "hello "
After strcat():  s1 = "hello world"

o strchr(s1,c) -- look for character c in string s1 return pointer to this character

/* EXAMPLE strchr() use */
#include <stdio.h>
#include <string.h>

void main()
{
	char s[20] = "Alex Ferworn";
	char c = 'F';

	printf( "s = \"%s\"\n", s );
	printf( "c = '%c'\n", c );
	printf( "strchr(s,c) = \"%s\"\n", strchr(s,c) );
}

produces

s = "Alex Ferworn"
c = 'F'
strchr(s,c) = "Ferworn"


o strstr() -- finds the first occurrence of one string in another

/* EXAMPLE strstr() */
#include <stdio.h>
#include <string.h>

void main()
{
	char *string = "scatter";
	char *substring = "tt";
	char *result;

	result = strstr( string, substring );
	printf( "strstr(\"%s\",\"%s\") == \"%s\"\n",
				string, substring, result );
}

produces;

strstr("scatter","tt") == "tter"

o strcmp() -- compares two strings

see the example at the end of these notes

Multidimensional Arrays, The Basics
------------------------------------
o An array of arrays is a multidimensional array.
o C supports as many dimesions as you can think of.

Example: The magic square

17	24	1	8	15

23	5	7	14	16

4	6	13	20	22

10	12	19	21	3

11	18	25	2	9

static int magic [5][5] = { 
			{17,24,1,8,15},
			{23,5,7,14,16},
			{4,6,13,20,22},
			{10,12,19,21,3},
			{11,18,25,2,9} 
				};

o To access an element in a multidimensional array, 
	you specify as many subscripts as necessary.
o Stored in row-major order, means the last subscript 
	varies the fastest. For exampe, let's store the 
	magic square.
o When initializing a multidimensional array, you may 
	enclose each row in braces. 
o If there are too few intializers, the extra elements 
	in the row are initialized to zero.

loc	000 001 002 003 004 005 006 007 008 009 010 011 012 013 ...
val	17  24  1   8   15  23  5   7   14  16 ...

Making it messy with pointers
-------------------------------
o Suppose we had the following declaration;

long array[2][3] = {{0,1,2},{3,4,5}};

o The array reference

array[1][2] is the same as *(array[1] + 2) 
is the same as *(*(ar+1)+2)   ...   neat trick eh?

Avoiding a problem with syntax

o Watch out for the following;

	array[1][2] not array[1,2]

even though both are legal, the first is an array reference
and the second uses the comma operator and probably
doesn't do what you want.

Passing Multidimensional Arrays as Arguments
---------------------------------------------
Here is an example of how to do it;

...
void main()
{
	float array[5][6][7];
	func0(array);
	func1(array,5,6,7);
}

func0(float received_arg[][6][7]) 
/* the compiler interprets this as 
float (*received_arg)[6][7]; */
{
	...
}

func1(float ***receive_arg, int row, int col, int plane)
/* welcome to the world of pointer math */
{
	...
}

o Exercise (which I suggest you do!!!)
-----------------------------------------
Write a C function which takes as arguments 3 matrices. 
The first will have dimensions n rows by m columns and 
the second will have dimensions m rows by n columns and 
the third will have n rows and n columns. 
Muliply the first by the second and store the result in the third array.  

o An example using both 2D arrays and strings

/* Example: a program to sort a file of at most MAX_NUM words into ascending 
order and output each unique word. First the file is echoed to stdout */

#include <string.h>
#include <stdio.h>

#define MAX_SIZE 81
#define MAX_NUM 1000

void main()
{
	char words[MAX_NUM][MAX_SIZE]; 	/* array to hold strings (words) */
	char *wordptr[MAX_NUM];			/* array to point at contents of previous array */
	int counter=0,i,sorted=0;
	char *temp;
	
	while(scanf("%s",words[counter]) != EOF)	/* read words until EOF */
	{
		printf("%s ",words[counter]);			/* echo the file to stdout */
		wordptr[counter] = words[counter];		/* set up the pointer */
		counter++;
	}
		
	while(!sorted)						/* bubble sort the pointers */
	{
		sorted = 1;
		for(i=0;i<counter-1;i++)
			if(strcmp(wordptr[i],wordptr[i+1]) > 0)	
				/* strcmp(s1,s2) compares the strings
				s1 and s2, if s1 is bigger it returns a
				positive integer, if the same it returns
				zero and if smaller it returns a negative
				integer */
			{
				sorted = 0;
				temp = wordptr[i];
				wordptr[i] = wordptr[i+1];
				wordptr[i+1] = temp;
			}
	}
	
	printf("\n\n");	
	temp = "E4Mna1@";	/* set temp to something that won't be in 
				the file */
	
	for(i=0;i<counter;i++)				/* go through list */
		if(strcmp(temp,wordptr[i]))		/* if this is not the same as last word 
							print it */
		{
			printf("%s\n",wordptr[i]);
			strcpy(temp,wordptr[i]);	/* change temp to be current word */
		}
}
		
o Exercise: Improve the program by making the part that sorts into a function