char*, char[] and string

Hi,

Is there a good article which gives a good explanation on the differences, relationships and usages for those three types in C++?

It is a very fundamental question but sometimes get me confused when I switch between Java/C# and C++.

Thanks

Chris
char* is pointer to a char.

char[] is an incomplete type and indicates a character array.

std::string is a string (class) from the standard (template) library.
thanks. Leave the string alone now, so at what situation you may want to use char* and when you may want to use char[]? For example, as I know, there is no terminator for char[] but there is one for char*. So for

char* a = "abc";
char[] b = {'a','b','c'};

the real length for a is 4 and b is 3. is that right? sometimes, those minor differences it caused problem ...

and what "an incomplete type" means here?

Thanks
If you set b to "abc" like you did to the pointer then it would have a length of 4.

You probably won't want to use a pointer or an array very often. For general use, you're best off using std::string and if you need to pass it to a function that requires a char*, it has a member function that returns a char* to the string it contains.
We typically, use [] to declare arrays.
And use * to declare pointers or function parameters.

e.g.
char name[] = "cplusplus.com"; // an array declaration (14 bytes including terminating null)
char *ptr = name; // a pointer (4 bytes?) initialised with name

void printname(const char *name);
few more points
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<cstdio>
#include<cstring> // string operations
#include<iostream>
using namespace std;


int main()
{
	char* pA="abc";
	char A[3]={'a','b','c'};
	cout << "pA is " << pA << endl; // It displays "abc"
	cout << "A is " << A << endl;// It may display wrongly because it does not know what is the last element
	char B[]={'a','b','c','\0'}; // added a null character at the end;
	// contents of B is now similar to pA
	cout << "B is " << B << endl; // It displays "abc"
	int lengthpA=strlen(pA);
	cout << "length pA is " << lengthpA << endl; // displays 3
	int lengthA=strlen(A);
	cout << "length A is " << lengthA << endl;// may display the size wrongly though we have set size to 3
	// most of the size calculations needs a null character to indicate the end of the array
	// null character is not counted in the size
	int lengthB=strlen(B);
	cout << "length B is " << lengthB << endl;
	// B is a character string and all string operations can be done, but not for A
	strcat(B,B);
	cout << "now B is " << B << endl;
	char C[40];
	strcpy(C, pA);
	cout << "now C is " << C << endl;
	// coming back to char* pA="abc"
	// the right hand side "abc" is of the const char* type
	// compiler allocates a special bock of memory for it
	void* addr= reinterpret_cast<void*>(pA); // to display the address pA pointing to
	cout << "pA points to " << addr << endl;
	// create another pointer
	char* pB="abc";
	void* addr1= reinterpret_cast<void*> (pB); // to display the address pB pointing to
	cout << "pB points to " << addr1 << endl;
	// You note that both points to the same memory
	// Compiler is cleaver enough to understand defined constant literals 
	// and it is available globally so that it can reassign it
	// that brings another point since pA and pB are const char*, you can not modify the contents
	// through pA and pB
	pA[0]='A'; // will give you Access error (or crash)
	// but we can modify the array that we declared
	B[0]='A';
	cout << "now B is " << B << endl;
	

	
	return 0;
}
Thanks for the help so far. anilpanicker's sample is actually the "article" I am looking for. I put it in my sandbox as the starting point for it.

I have some questions for the sample, as for

// the right hand side "abc" is of the const char* type
// compiler allocates a special bock of memory for it
void* addr= reinterpret_cast<void*>(pA); // to display the address pA pointing to
cout << "pA points to " << addr << endl;
// create another pointer
char* pB="abc";
void* addr1= reinterpret_cast<void*> (pB); // to display the address pB pointing to
cout << "pB points to " << addr1 << endl;

pA and pB are declared as char*, not const char*. Why can't pA[0]='A'; work? Or any char* declared locally always const in default?

Thanks





Because string literals ("this is a string literal") are stored in read-only memory.
does it mean

char* x = "a" is always equal to const char* x ="a";

for
char* x;
char* y = "a";
x = y; //Now x becomes const?


what Chewbob said is the answer, "abc" is a string literal and it has a const storage.
More on that you can read here
http://www.possibility.com/Cpp/const.html

1
2
3
4
5
6
7
8
char* x;
char* y="a";
x=y; // here x is pointing to a const char* but it is not a const char* type
//what I mean
char z[]={'a','b'};
x=z; // is valid
y=z; // valid
Thanks. This is a very interesting article. Seems a lot of on line sample codes related to char* manipulation are not right (even if it happen to work in certain compilers).
For example,

http://www.cprogramming.com/faq/cgi-bin/smartfaq.cgi?answer=1046053421&id=1043284392


I will get running error for 1, but not 2. As all operations are trying to modify to char*, should both 1 and 2 have probelm in running?

Saw another implementation for toupper in string as in 3. Seems a safe way is always to convert char* to string before any manipulation/chagnes, right?

Thanks

/*
* A C++ Version showing how to iterate an array, converting character case
*/

#include <cctype>
#include <iostream>

using std::cout;
using std::endl;

int main(void)
{
char hello[] = "Hello World";

cout << "Before conversion: " << hello << endl;

for (char *iter = hello; *iter != '\0'; ++iter)
{
*iter = std::tolower(*iter);
++iter;
}

cout << "After conversion: " << hello << endl;

return 0;
}
/*
Output:
Before conversion: Hello World
After conversion: hello world
*/


2.

/*
* A short function to convert an array to uppercase,
* showing that we don't need to worry about non-character
* elements.
*/
#include <stdio.h>
#include <ctype.h>

void upstr(char *s)
{
char *p;

for (p = s; *p != '\0'; p++)
*p = (char) toupper(*p);
}

int main(void)
{
char mystring[] = "Some 1234 text 5678 here!";
puts(mystring);
upstr(mystring);
puts(mystring);
return(0);
}

/*
* Program output:
Some 1234 text 5678 here!
SOME 1234 TEXT 5678 HERE!
*
*/


3.
std::string data = "Abc";
std::transform(data.begin(), data.end(),
data.begin(), ::toupper);

cout << data << endl;
In example 1, *iter = std::tolower(*iter); should be *iter = tolower(*iter);.

I would also expect that example 3 should have data.begin(), toupper); instead of data.begin(), ::toupper);

toupper/tolower are old C macros as I recall.
Topic archived. No new replies allowed.