From: Carmen Sei on
why the following compile is OK

but will crash when execute?

the problem seem to in -
convertToUppercase( phrase );

==========
// Converting lowercase letters to uppercase letters
// using a non-constant pointer to non-constant data.
#include <iostream>
using std::cout;
using std::endl;

#include <cctype> // prototypes for islower and toupper
using std::islower;
using std::toupper;

void convertToUppercase( char * );

int main()
{
//char phrase[] = "characters and $32.98";

char * phrase = "characters and $32.98";

convertToUppercase( phrase );

return 0; // indicates successful termination
} // end main

// convert string to uppercase letters
void convertToUppercase( char *sPtr )
{
while ( *sPtr != '\0' ) // loop while current character is not '\0'
{
if ( islower( *sPtr ) ) // if character is lowercase,
*sPtr = toupper( *sPtr ); // convert to uppercase

sPtr++; // move sPtr to next character in string
} // end while
} // end function convertToUppercase
From: Carmen Sei on
to declare a string like

"abcd"

I should never use char * right?

i should always use const char * for string declare?

or i should always use char[]?


From: Alf P. Steinbach on
* Carmen Sei:
> why the following compile is OK
>
> but will crash when execute?
>
> the problem seem to in -
> convertToUppercase( phrase );
>
> ==========
> // Converting lowercase letters to uppercase letters
> // using a non-constant pointer to non-constant data.
> #include <iostream>
> using std::cout;
> using std::endl;
>
> #include <cctype> // prototypes for islower and toupper
> using std::islower;
> using std::toupper;
>
> void convertToUppercase( char * );
>
> int main()
> {
> //char phrase[] = "characters and $32.98";
>
> char * phrase = "characters and $32.98";

The string literal has type 'char const [n]' in C++.

Implicit conversion from literal string to 'char*' is only supported for C
compatibility.

You should not use it.

Instead, use std::string:

std::string const phrase = "as�dljkasdl�kjasdl�kj";

Of course that doesn't match very well with your convertToUppercase functon.


> convertToUppercase( phrase );
>
> return 0; // indicates successful termination
> } // end main
>
> // convert string to uppercase letters
> void convertToUppercase( char *sPtr )
> {
> while ( *sPtr != '\0' ) // loop while current character is not '\0'
> {
> if ( islower( *sPtr ) ) // if character is lowercase,

Well, this stuff is also dangerous, at least for users in non-English speaking
countries. A basic C library character oriented function takes int argument,
but expects and requires a value corresponding to unsigned char. You need to
cast the argument to unsigned char to handle non-English characters correctly.

The islower() test is redundant, but if you had a valid reason to use islower()
you should wrap it in a more safe function, like

bool isLower( char c )
{
return !!std::islower( static_cast<unsigned char>( c ) );
}

Then use isLower, not std::islower.


> *sPtr = toupper( *sPtr ); // convert to uppercase

And ditto.


> sPtr++; // move sPtr to next character in string
> } // end while
> } // end function convertToUppercase


Cheers, & hth.,

- Alf
From: Igor Tandetnik on
"Carmen Sei" <fatwallet951(a)yahoo.com> wrote in message
news:r4gdv3lrrv3s93fr20mtnb5u6rsk0sj5n8(a)4ax.com
> why the following compile is OK
>
> but will crash when execute?

String literals (like "abcd") should not be modified. VC compiler
actually stores them in a block of memory marked read-only, so any
attempt to modify them generates a hardware exception (what you call a
crash).

For backward compatibility with C, a string literal (whose type,
formally, is an array of const char) can be implicitly converted to
char*, which gives a false impression that it can in fact be written to.
It can't. Don't do that.

String literals should not be confused with a special form of
initializer that can be used for char arrays:

char* p = "abcd"; // string literal
char arr[] = "abcd"; // initializer

The latter is simply a more compact form of this equivalent statement:

char arr[] = {'a', 'b', 'c', 'd', '\0'};

Character arrays can of course be modified (whether initialized with
what looks like a string literal but isn't, or otherwise).
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


From: Alex Blekhman on
"Igor Tandetnik" wrote:
> For backward compatibility with C, a string literal (whose type,
> formally, is an array of const char) can be implicitly converted
> to char*, which gives a false impression that it can in fact be
> written to.

Unfortunately, no version of MS C++ compiler (including VC++2008)
does give a warning about that even with /W4. I can see this
mistake made by novice programmers (or those with Java background)
almost every day at my work.

Alex