Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

String manipulation in vc++ 2

Status
Not open for further replies.

fcsohn

Programmer
Dec 26, 2004
3
KR
#include <iostream>
using namespace std;

int main(void)
{
char* str = "joom";
*str = 'z';
cout << str << endl;
return 0;
}

/*
for above string manipulation
Borland compilers show no error message
but for the VC++6.0 compiler under visual enviroment,
it has been reported that it makes error message
in run time. printing no string on screen and shows
query dialog box if the user would like to report this
error to Microsoft.
Some one says it is syntax error to modify constant
string of "joom".
But why there isn't any error message during compilation,
and wonder how to explain the state of no error message for the same source under command line enviroment.
I would appreciate to the good advisor.
Thank your for your attentions.
*/



 
I thought that you were not allowed to modify static const strings (ie as you have declared them).

If you did :

char* str = new char[5];
strcpy(str, "joom");
*str[0] = 'z';

then you'd be OK.

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
The C++ Programming Language by Stroustrup on page 90 makes a passing reference to your question.

Speaking of char* string literals:
"It is... an error to try to modify a string literal through such a pointer."

char* p = "Plato";
p[4] = 'e'; //error: assignment to const; result is undefined

"This kind of error cannot in general be caught until run-time, and implementations differ in their enforcement of this rule."

Here is some code I experimented with:

//TekTips: Restrictions on string literals

//char* initialization
char *stringtest = "John";
//char *stringtest = 'J'; //Can not initialize with character
//char *stringtest = {'J'}; //even in initializer list

//char* assignment
stringtest = "John"; //Can reassign a string to a char* but not a character to its element. Strange.
//stringtest[0] = 'J'; //run-time error for most implementations because Stroustrup says you can't assign to a constant


//char[] initialization
char chararraytest[] = "John";
//char chararraytest2[] = 'J'; //Can not initialize without the use of a initializer list {}
char chararraytest2[] = {'J'};

//char[] assignment
chararraytest[0] = 'J';//Can reassign a character to an element of char[] but not a string to its pointer
//chararraytest = "John"; //compile-time error (can not convert from const char [5] to char [5])
//Apparently character 'J' is not considered a constant the way "John" is considered one


//Bottom line: char* is similiar to const char[] in that its elements can not be assigned
// char* can be reassigned strings even though its constant. Strange.
// const char[] cannot be reassigned strings because it's constant
// char[] cannot be reassigned strings because of type mismatch
// Stroustrup says you should take it upon yourself to declare all char* string literals constant.
 
>char* can be reassigned strings even though its constant.

No it is not constant, a char* is a char* nothing constant about that.

>Strange

Nothing strange here.

"Foo" is a literal constant though, and when you do something like this:
Code:
 char* s = "Foo"
It is like saying: s points to the literal constant "Foo".

If you then dereference it like:
Code:
 *s = 'B'
It is like saying: Change the first element s points to to 'B'

But since s points to a literal constant, you're trying to change something inside the literal constant and that is of course a no-no.

If you do a new assignment like :
Code:
s="Bar";
It is like saying: s points to the literal constant "Bar

You're simply letting s point to another literal constant, you're not trying to re-assign the elements in any literal constant - and hence it is quite OK.

You still think it is strange?

/Per
[sub]
www.perfnurt.se[/sub]
 
//char* to new char instantiation
char* str = new char;
char* str2 = new char[];
char* str3 = new char[5];

//char* to new char assignment
str3[0] = 'z'; //character assignment
str3 = "matt"; //string assignment
str3 = "mattttttty"; //resizable

It looks like char* to new gives you the best of both worlds of char* and char[]
 
I belive you're a bit confused.

Code:
char* s = new char[5];
Is like syaing: s points to allocated (non constant) chars.

If you then do
Code:
s = "matt"
It is : s points to the literal constant "matt".
Whatever allocated with new is lost since you simply let s point elsewhere.

Code:
str3 = "mattttttty"; //resizable
Resizable?!? No! You just pointing to yet another literal constant.

Btw, all this char* stuff is sooo C. In C++ we use std::string....


/Per
[sub]
www.perfnurt.se[/sub]
 
Thanks for the clarification.

One last question:

char chararraytest[] = "John";

In this example is a const char[] being converted to a char[]?

Thanks
 
>In this example is a const char[] being converted to a char[]?

Nope. There is
1) A constant string litereral "John".
2) A char[] named chararraytest.

char[] and char* is pretty much the same thing: A pointer to some address of a char array.

Code:
char chararraytest[] = "John";
is the same thing as Ive said before : chararraytest is simply told to point at some literal constant.

/Per
[sub]
www.perfnurt.se[/sub]
 
The type of a string literal is "array of the appropriate number of const characters," so "Bohr" is of type const char[5]."

Stroustrup pg.90

Doesn't this imply a string literal is const char[]?
 
Yeah, you're right, I forgot that the char[] declaration automatically allocates/assigns required amount of chars based on the string literal it's initialized with.

/Per
[sub]
www.perfnurt.se[/sub]
 
Are these assumptions correct as far as dynamic strings are concerned?

char* str3 = new char[5];
str3[3] = 'A'; //run-time heap memory
str3[15] = 'A'; //run-time heap memory

str3 = "Robert"; //Pointer now pointing to a string literal requiring static stack memory

Thanks a lot for your help. I'm trying to channel my OCD in productive ways. :)
 
Yeah they are correct. Though the element at str3[15] is not allocated.

Note that when using new you should also delete.
In the real world use std::string.
Code:
#include <string>

{
  std::string s = "Foo"; // Initialize
  s = "Bar"; // Re-assign
  s = "Foo Bar"; // Resize
  if (s == "Fnurt") { ... } // Compare
} // s properly deallocated when it goes out of scope.



/Per
[sub]
www.perfnurt.se[/sub]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top