Thread overview
Why does char[] of one character become a char?
May 24, 2004
David L. Davis
May 24, 2004
Andy Friesen
May 24, 2004
David L. Davis
May 24, 2004
Stephan Wienczny
May 24, 2004
Norbert Nemec
May 24, 2004
Below is the start of some code I'm porting from VB6 to D, it's a pretty simple propercase() function for use on names and addresses mainly. Anyway I can't figure out why where char[] sStr = " kingpin for a day! "; and I do for...next loop thru with this code, where sStr[i] = toupper(sStr[i]); that I get an error from dmd v0.90?  (char[] == char FALSE, but I'm passing in char[], and char[] == char[] which is TRUE)

Thanks in advance for any help, and / or pointers. :))

//=================
//Code starts here
//=================
import std.c.stdio; //toupper(char[] sStr);
//import std.ctype; // toupper(dchar char);
import std.string;

const int PC_ALL = 1;

// Wish in, out, and inout could be all caps, or at
// least allow either an all lowercase or uppercase version.
char[] propercase
(
in char[] sStr,
in int ioption
)
{
const char WHITESPACE = '\x20';

int   i                 = 0; int   iSpecialCharCount = 0;

//Currently ioption is being ignored.
if ( sStr.length > 0 )
{
/*
Initial pass - only capitalizes the very 1st character,
not very useful if you ask me.
*/
sStr = capitalize( tolower( strip( sStr ) ) );

for ( i = 0; i < sStr.length; i++ )
{

if (sStr[i] == WHITESPACE) iSpecialCharCount = 1;

/*
The toupper() function seems to treat a parameter of a
"D String of one character" as if it's a char only
(why should char[0] be the same as a char?).
*/
if (iSpecialCharCount != 0)
{
/*
Errors:
1) "function toupper (char[]s) does not match argument types (char)
2) "cannot implicitly convert char[] to char"
--------------------------------------------------------------------

sStr[i] = toupper( sStr[i] );
*/

/*
Error: even when I cast it, it doesn't work.
1) "cannot implicitly convert char[] to char"
-------------------------------------------------------------
sStr[i] = toupper( cast(char[])sStr[i] );
*/

iSpecialCharCount = 0;
} // end-for

printf("Char=%c\n", sStr[i]);

} // end-for

} // end-if


int isroman
(
in char[] sSubStr,
in int    iPos
)
{
const char[] ROMAN = "IVXLCDMivxlcdm";

return find( ROMAN, sSubStr[iPos] );

}


return sStr;

} // end-function propercase

int main()
{
char[] sStr = " kingpin for a day! ";

printf("Start...\n");
printf("ProperCase=%.*s\n", (propercase(sStr, 1)));
printf("End...\n");
return 0;
}


May 24, 2004
David L. Davis wrote:

> Below is the start of some code I'm porting from VB6 to D, it's a pretty simple
> propercase() function for use on names and addresses mainly. Anyway I can't
> figure out why where char[] sStr = " kingpin for a day! "; and I do for...next
> loop thru with this code, where sStr[i] = toupper(sStr[i]); that I get an error
> from dmd v0.90?  (char[] == char FALSE, but I'm passing in char[], and char[] ==
> char[] which is TRUE)

a[n] is a single element, not an array.  If you need it to be an array, use a[n .. n + 1] to create a one-element-long slice of the string.

This suggests that toupper(char) needs to be added to Phobos, though.

> Thanks in advance for any help, and / or pointers. :))

Try indenting your code once and awhile? ;)

 -- andy
May 24, 2004
If I do understand what you mean, the compiler is correct ;-)

A char[] is an array of type char.
Have a look at the documentation about arrays:
http://www.digitalmars.com/d/arrays.html

Let me try to give you an example of how you can write the function in D:

import std.ctype;

char[] prop (in char[] s)
{
	bit last_whitespace = true;	
	
	foreach(int i, char c; s)
	{
		if (isspace(c))
		{
			last_whitespace = true;
			continue;
		}else if (last_whitespace)
		{
			last_whitespace = false;
			c = toupper(c);
		}
	}
	return s;
}
May 24, 2004
Don't forget "copy on write":

Stephan Wienczny wrote:

> If I do understand what you mean, the compiler is correct ;-)
> 
> A char[] is an array of type char.
> Have a look at the documentation about arrays:
> http://www.digitalmars.com/d/arrays.html
> 
> Let me try to give you an example of how you can write the function in D:
> 
> import std.ctype;
> 
> char[] prop (in char[] s)
> {

        s = s.dup;  // copy on write: otherwise the original string
                    // might be overwritten.

> bit last_whitespace = true;
> 
> foreach(int i, char c; s)
> {
> if (isspace(c))
> {
> last_whitespace = true;
> continue;
> }else if (last_whitespace)
> {
> last_whitespace = false;
> c = toupper(c);
> }
> }
> return s;
> }

A more intelligent version would defer the .dup until it really is necessary.
May 24, 2004
In article <c8t8tc$2tbb$1@digitaldaemon.com>, Andy Friesen says...
>
>a[n] is a single element, not an array.  If you need it to be an array, use a[n .. n + 1] to create a one-element-long slice of the string.
>
>This suggests that toupper(char) needs to be added to Phobos, though.
>
>Try indenting your code once and awhile? ;)
>
>  -- andy

Thanks Andy, Stephan, and Norbert for your quick replys.

I'd like to point out that I was aware the a single array element would be pass as a char in C/C++, but somehow I thought that char[] was an object (a D String of sorts) since it knows it's own length (as if it were a Class Object). So with that in mind, I thought passing a array of characters that only had one element into a D toupper() function that allows an array of characters as a parameter, that it should work. Anyways, Thanks for pointing to me that D is still C in many ways. :)

* Stephan and Norbert: I'll try the foreach(,;)...loop with varible.dup within
my code, cause it does look cleaner and easier to read (and it's better than a
for...loop).

* Andy: I always indent my code, but since I posted it thru the Web, and I guess because I used space to indent with and not tabs (a programming habit of my where I like using spaces over tabs)...it all disappeared. :P But thanks for pointing out anyway. Also I think the a toupper(char) would be very helpful to have in the Phobos Standard Library. (I hope it makes it in before D v1.0 :) )