Journal Articles

CVu Journal Vol 12, #1 - Jan 2000 + Letters to the Editor
Browse in : All > Journals > CVu > 121 (30)
All > Journal Columns > LettersEditor (132)
Any of these categories - All of these categories

Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.

Title: The Wall

Author: Administrator

Date: 08 January 2000 13:15:34 +00:00 or Sat, 08 January 2000 13:15:34 +00:00

Summary: 

Body: 

And Further Corrections

Dear Francis,

Re: You Write, the Editor Replies - C Vu 11.6

It's that ISBN stuff again... In your reply (to Catriona?) about the removeDashes function you say that you would prefer to code that function as:

char[]  removedashes (char sourcestring[]) {
  int i=0;  
  int j=0;
  while (sourcestring[i] == sourcestring[++j])
    if (sourcestring[i] != '-' )  ++i;
  return sourcestring;
}

I assume there was a typo in that while expression, since as it stands it will patently fail with the == and the pre-increment of j (I think...) You asked what readers think - here are my thoughts.

  1. change that while expression to:

      while (sourcestring[i] = sourcestring[j++] )
    

    has a better chance of working! I have no gripes about omitting the comparison with '\0' (though I know of others that have stronger views on the subject!).

  2. That said, If I had to code a removedashes() it would look more like:

    char* removedashes(char *source) {
      char *p,      /* for reading bytes from 'source' */
          *q;      /* for writing back bytes to 'source' */
      for(q = p = source; *p; ++p) if (*p != '-') *q++ = *p;
      *q = '\0';  /* terminate resulting string */
      return source;
    }
    

    I think the choice of while/for is personal, but I'm not so sure about the choice of [] (array) or * (pointer) for the declarations. To my mind, either is acceptable in the above context, and I personally find the '*' declarations more readable. And at the risk of being pedantic, find the '*' more descriptive - in the sense that removedashes() returns the address of the first element of an array rather than the array itself; i.e. a pointer value. I'm happy to be shot down in flames for this heresy, but the above function does work as expected (for me!).

  3. The eliminate() question. Here's my version:

    #include <stdio.h>  /* for def'n of NULL */
    #include <string.h>  /* for def'n of strchr() */
    char* eliminate (const char *these, char *from) {
    char  *p,    /* for reading bytes from 'from' */
        *q;    /* for writing back bytes to 'from' */
      for (q = p = from; *p; ++p) {
        if (strchr (these, *p) == NULL) *q++ = *p;
      }
      *q = '\0';  /* terminate resulting string */
      return from;
    }
    

This is maybe not the most efficient solution, but at least it works, given of course that *these or these[] reference a null-terminated array of char - a reasonable assumption I think given the specified prototype with no size parameter. Without this assumption strchr() would be inappropriate :-( (I also took the liberty of adding a const in there on the grounds that I think these[] should not be changed by the function.)

However, a function to eliminate certain characters might well be optimised (e.g. for speed) in a real-life situation where these[] was effectively a "fixed" set of unwanted chars. In such a case I'd be tempted to set up an array of 256 elements (unsigned bytes for speed, bits for space) and use an indexed lookup to replace the many calls to strchr. Thus there would be a once-off initialisation function to set up e.g. the discard[] array with TRUE/FALSE elements, and the

if (strchr (these, *p) == NULL)

line would be replaced with something like

if (! discard [*p] )

And if I had the choice I'd make sure that all 'char's were unsigned - either by explicit declaration or compiler switch. I've been bitten too many times using signed chars in such situations!

Hope there's something here that's usable for C Vu,

Pete Disdale

Thanks. One of those errors was a typo. The use of char[] for a return type was done with malice aforethought. Now a word about [] versus * in parameter declarations. I strongly advocate the [] in the prototype in the header file and in documentation because it tells the user something vital, this function processes an array. I prefer to use pointer notation in the definition (implementation file) to remind me that this is how the local code sees it.

I slightly changed the layout of your code. However when using structures (loops etc.) I advocate using braces for the controlled statement unless it will fit on a single line. Some insist that braces are always used. Personally I find that less helpful. Finally I always place cv (const, volatile) qualifiers to the right of what is being qualified. 'No exceptions' leads to 'no surprises'.

Notes: 

More fields may be available via dynamicdata ..