XML

kent logo

CO538 Anonymous Questions and Answers Keyword Index

This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.

To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.

Keyword reference for string-handling

2012

Question 35 (2012):

Submission reference: IN2189

Is there a way to join strings together easily? For example, in Java you can just use '+'. Thanks.

Answer 35:

Classical occam was definitely not designed for string handling, :(. Strings are BYTE arrays and arrays have fixed lengths, with those lengths fixed at compile time, :( :(. For further Q&As on string difficulties, follow the lilnks to "strings" and "string-handling" in the keyword index.

We did provide a string handling library but it's painful to use. A string has to be maintained in two variables: a BYTE array sufficiently long and an INT recording its actual length. (Aside: with occam-pi, this could be simplified to a single RECORD variable – see "Shared-etc" slides 94-116 – but it would still be a painful.) If an attempt is made to extend a string beyond the size allowed by the BYTE array, it just crashes! To try it out (not recommended), include:

    #INCLUDE "string.module"

in your program.

However, occam-pi has dynamic arrays whose size is set at run-time, which means they can also be changed – see "Mobiles" (which is not an examinable part of this course) slide 14. Further, occam-pi has user-defined operators and user-defined types, which means that a library can be set up defining a dynamic STRING type and a whole bunch of infix operators (e.g. "+" for joining them). This would be a useful mini-project (or part of a larger one).

Having said the above, why do you want to join strings together for this assessment (Dining Phils Animation)? The college processes should not be working with strings – see the last paragraph ("Do not attempt ...) of the answer to Question 31 (2012). Only the display process needs to deal with strings and, then, only to output them to the screen!. To "join" strings together for such output is unnecessary – simply output them in sequence.

Keywords: q7 , strings , string-handling

2011

Question 40 (2011):

Submission reference: IN2071

Since strings within a list have to be padded (see Question 104 (2003)), I'd like to keep track of the actual length of a string (sans padding).

For example:

    "Cherry Tree": 11
    "Cuban	": 5
    ...
    "Lady Luck	": 9

Now, I believe 3D arrays are one way to achieve this. 2D arrays blow my mind far enough, but 3D takes it to the next level of discombobulation!

This feels like it should work:

    VAL [][][]BYTE a IS [["Cherry Tree", [11]], ["Cuban      ", [5]]]:

... but woefully gives me:

    table elements are of different types

What am I missing? Can it be simplified?

Answer 40:

The issue here is that "[11]" is of type "[1]BYTE", rather than of type "[11]BYTE". The simplest method (in my view anyhow) is to use a RECORD type (which we've now covered in the lectures) along the lines of:

    VAL INT MAX.STRING.LEN IS 128:

    DATA TYPE MY.STRING
      RECORD
        [MAX.STRING.LEN]BYTE str:          --* string data.
        INT len:                           --* actual length of string.
    :

Then you can easily create an array of these things:

    [42]MY.STRING string.table:

You'll probably want some helper PROCs to manage and display these sorts of things, but that's trivial enough:

    PROC set.my.string (MY.STRING s, VAL []BYTE str)
      SEQ
        IF
          (SIZE str) > MAX.STRING.LEN
            s[len] := MAX.STRING.LEN
          TRUE
            s[len] := SIZE str
        [s[str] FOR s[len]] := [str FOR s[len]]
    :

    PROC out.my.string (VAL MY.STRING s, VAL INT padding, CHAN BYTE out!)
      out.string ([s[str] FOR s[len]], padding, out!)
    :

Both of the above bits of code use array slices which haven't been covered in the lectures yet, but their operation is largely straightforward :-) — feel free to read up on them; they're at the end of the Shared-etc. slides.

Keywords: q7 , strings , string-handling

Referrers: Question 42 (2011)

2006

Question 33 (2006):

Submission reference: IN995

How do you create an array of strings? This is the closest I have got:

  VAL [][]BYTE name.phil IS ["Bob", "James", "Fred", "Jane", "Amy"]:

But it doesn't work, and theres not a whole lot of information online :( Any hints?

Answer 33:

See Question 104 (2003) in particular, and other questions relating to strings and string-handling. Lots of stuff on-line!

Keywords: strings , string-handling

Referrers: Question 58 (2007)

2004

Question 66 (2004):

I "think" I am nearly there with q6 I just have one problem left. If all the names are the same size then my code works fine :-). However if the names are different sizes it goes a bit wonky. Say I have:

    Mandy 551
    Mandy 976
    Sonya 577
    Hubert 969
    Mandy 127

And I have "[INT]BYTE temp:", where the max length for a name is 8 and a space is represented as ~, "temp" would hold values something like this:

    1) Mandy~~
    2) Mandy~~
    3) Sonya~~
    4) Hubert~
    5) Mandyt~

The `t' of "Hubert" is not being cleard when I push "Mandy" into it. Well thats all I can come up with why it is not working. How would I clear a string to make it all spaces?

Any tips would be great!

Answer 66:

To clear all the elements of a byte array to spaces is trivial (and obvious!):

    SEQ i = 0 FOR SIZE my.array
      my.array[i] := ' '

But it sounds like you're not calling "make.string" correctly. Whenever you read from the tagged protocol channel into the byte array (along with the number of bytes, say "count", communicated for the name and the associated mark), only the first "count" elements of the array are changed -- the rest are not touched. You must call the "make.string (name, count)" procedure, where "name" is the name of the byte array. This clears any bytes left over in "name" to zero (the ASCII NUL character) -- that is all bytes apart from the first "count" elements. That will erase your left-over `t~'.

Keywords: q6 , string-handling


Question 55 (2004):

In an previous anonymous question someone asked how to compare strings. The answer said to pass these BYTE arrays through the "make.string" function and then use "compare.string". However, I get the error:

    make.string is not a function

Is this a provided function or do we have to make it ourselves ?

Answer 55:

"make.string" is provided, but it's not a function -- it's a procedure. It adjusts the BYTE-array given to it as a parameter so that the string can be used with the other string functions -- which are really functions (e.g. "compare.string" and "equal.string"). The the answer to Question 50 (2003) for a code example on how to use it.

Keywords: q6 , string-handling

2003

Question 71 (2003):

For:

    PROC make.string([]BYTE a, VAL INT length)

it doesnt output to anything it seems, unlike the `copy.string'

does this means it just changes the variable passed to it for the string part to the length that is passed to it?

ie if we had:-

    []BYTE name1:
    INT length1:

    make.string(name1, length1)

would this change the variable `name1' to be the length passed to it?

Answer 71:

Yes, it modifies the contents of the array passed to it as a parameter. The array itself is left untouched.

In your code fragment, you have this:

    []BYTE name1:

This is an illegal declaration. The array-size must be given, e.g.:

    [max.name.length]BYTE name1:

Also, when you call `make.string (name1, length1)', it's important that `length1' has been initialised -- perhaps to zero.

Keywords: string-handling


Question 68 (2003):

is an empty string represented as ""

e.g. `equal.string(name,"")' would check if the name varible was empty

Answer 68:

Yes, that comparison will return TRUE, if at some point, previously, this happened:

    make.string (name, 0)

Keywords: q6 , string-handling


Question 50 (2003):

To use `equal.string', I understand that I have to make the string from the array of bytes first using `make.string', but whenever I try to use `make.string' the compiler tells me that `make.string' is not a function. And indeed when I look at `string.occ' in the libsrc directory it is a PROC not a FUNCTION. Do I need to re-write `make.string' as a function or is there another way ??

Answer 50:

`make.string' adjusts an existing string (array of BYTEs) -- it does not create a new one. The function of this (if you read the source code) is to replace all the non-string bytes with a special token (ASCII NUL). In effect, it allows other routines to work out the length of the string -- which will likely be different from the size of the array.

For example:

    PROC string.test ()
      [15]BYTE s1:
      [10]BYTE s2:
      SEQ
        --{{{  initialise s1
	[s1 FOR 5] = "Hello"
	make.string (s1, 5)
	--}}}
	--{{{  initialise s2
	s2 = "HelloWorld"
	make.string (s2, 5)
	--}}}
	IF
	  equal.string (s1, s2)
	    good ()
	  TRUE
	    bad ()
    :

See also the answers to Question 48 (2003) and Question 19 (2001).

Keywords: string-handling

Referrers: Question 55 (2004)


Question 48 (2003):

I'm stuck on q6. My program deadlocks and I don't know why. I have managed to work out that it is something to do with my `cell' procedure, and also it appears to me that the `string.equals' procedure doesn't work in my cells. Any help would be great thanks.

    [snip code]

Answer 48:

Questions such as this are not easily answered in this public forum. Consider emailing your seminar leader.

However, in response to your query, when using `equal.string', etc., you must first ensure that `make.string' has been used on the string. These strings are not really strings -- they are arrays of BYTEs. `make.string' adjusts the array so that comparisons, etc. are based on the length of the `string', not the size of the array.

Keywords: q6 , string-handling

Referrers: Question 50 (2003)

2001

Question 19 (2001):

For Q6, if I have two strings called a and b and I want to use the compare.string function on them, how do I do it? Is it something like:

  compare.string (a, b)

Also, if I get back string.less or string.more, which of the two strings is being referred to as smaller or bigger than the other?

Answer 19:

Yes to your first question. Make sure you have read the documentation in libsrc/string.occ, which is part of the course library and which contains the string handling routines. Most important is that functions like compare.string (etc.) do not work unless the BYTE arrays on which they operate have first been processed by make.string.

To your second question, if compare.string (a, b) returns string.less, then a is less than b. That was meant to be obvious ... if you were at all unsure, a glance at the source code would have confirmed this ...

Note: if others have further questions about this assignment, please first refer to last year's Question 51 (2000) onwards.

Keywords: q6 , string-handling

Referrers: Question 50 (2003) , Question 54 (2003)

Valid CSS!

Valid XHTML 1.0!

This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
Last modified Mon May 20 13:50:33 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.