Why can std::cout print a char[]? [duplicate] - c++

This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 5 years ago.
Below code prints the entire string. I am confused why its does so.
char test[] = "jeff";
cout<<test<<endl;
The output is "Jeff", I was expecting it to print the value of char array "test", since test is pointer, pointer the first element which is 'J'.
Why is it printing the whole string, when I cout<<test??

Because of operator<< (basic_ostream<charT,traits>& os, const char* s); (#2 "character sequence" in that list) (slightly more technical list). test decays to a pointer, or char*, which then gets printed as a C-string.
It's the exact same reason cout << "Jeff"; works (instead of printing the address of "Jeff").

The first element is 'j', certainly, but a char* isn't meant to represent only one char, but a string of them. cout will keep reading chars til it find the null char, or '\0'. This is implicitly put there when you use a string literal such as "jeff".
To print only the first char, dereference the pointer to get it like cout<<*test<<endl;.

In C++ (as in C), strings are modeled as NUL-terminated character arrays I.e., the last character's ordinal value is 0, in your example it's character with index 4, inserted by the compiler immediately after the last "f" in "jeff". So in many contexts pointers to "char" are assumed to be NUL-terminated; in this case "cout" keeps printing characters until it hits the NUL character at the end, at which point it stops. C++ also has an actual string class, "std::string", that is in many ways superior to char arrays.

Related

Char array seems to append previous unrelated char arrays to itself? [duplicate]

char sentence[] ={'k','k','k','k','k','k','k','k'}; (8 character)
std::cout << sentence << std::endl;
Then output just "kkkkkkkk".
But if we decrement characters of array (i.e. preceding array have 8 character after less 8 character)
char sentence[] ={'k','k','k','k','k','k','k'}; ( 7 character)
std::cout << sentence << std::endl;
output:
kkkkkkk`\363\277\357\376.
The operand sentence decays to a pointer to first element of the array. The stream insertion operator overload that accepts const char* parameter requires that the pointer is to a null terminated array. If that pre-condition is violated, then the behaviour of the program is undefined.
sentence does not contain the null terminator character. You insert it into a character stream. The behaviour of the program is undefined.
Then output just "kkkkkkkk".
That's one potential behaviour. This behaviour isn't guaranteed because the behaviour of the program is undefined.
But if we decrement length of array then output kkkkkkk`\363\277\357\376.
That's one potential behaviour. This behaviour isn't guaranteed because the behaviour of the program is undefined.
char arrays are often used for null-terminated strings, but not always.
When you write
const char* str = "Hello";
then str is a pointer to the first element of a const char[6]. 5 for the characters, and the rules of the language make sure that there is room for the terminating \0.
On the other hand, sometimes a char array is just that: An array of characters. When you write
char sentence[] ={'H','e','l','l','o'};
Then sentence is an array of only 5 chars. It is not a null-terminated string.
This two worlds (general char array / null-terminated strings) clash when you call
std::cout << sentence << std::endl;
because the operator<< overload does expect a null-terminated string. Because sentence does not point to a null-terminated string, your code has undefined behavior.
If you want sentence to be a string, make it one:
char sentence[] = {'H','e','l','l','o','\0'};
Or treat it like a plain array of characters:
for (const auto& c : sentence) {
std::cout << c;
}
Try using
char sentence[] = {'k','k','k','k','k','k','k','k','\0'};
you must always use a '\0' at the end when you are declaring a char array manually and want to print it. Because either cout or printf function will look for '\0' character and will only stop printing if it finds '\0'. also make sure you wont you it in middle of your array as it wont print the complete array

defining a string in C++ with const char *str="Hello"; [duplicate]

This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 2 years ago.
I am a little confused here. In the statement const char *str="Hello";, str is a pointer to a char variable pointing to the first character 'H' of the string "Hello", so str should contain the address of the 'H' character. And yet, if I use cout<<str, it prints the entire string "Hello" and not the address.
And also, If I use cout<<*str to print the value stored in the address pointed to by str, it prints the char 'H' correctly.
Can someone please explain how and why this happens? This may be very basic, but an explanation would help me understand these concepts more clearly.
str is a pointer to a char variable
There is no char variable in the example. str does point to a char object.
Can someone please explain how and why this happens?
Because the binary operator << whose left hand operand is an output sream and right hand operand is a pointer to char is specified to print the entire string.
If the pointed char isn't within an array that contains the null terminator character starting from that character, then the behaviour of the program would be undefined. String literals are null terminated, so the example is correct.

The value of the pointer to char address [duplicate]

This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 7 years ago.
In VS C++ I have a simple declaration of a char variable and a pointer to char.
char mychar = 'c';
char *mypointer = &mychar;
When printing the value of mypointer using cout I would expect an 8 character address value like 0038FEDC to appear in console. Instead I am getting some strange results like:
c│■8, ck∙<, c;■8 etc...
Why these strange characters appear when outputting pointer to char values?
std::ostream, of which std::cout is an instance, has an overload for operator<< which treats char* as a pointer to the first character in a null-terminated string.
You are passing it a pointer of a single character, not a null terminated string. This causes undefined behaviour.
In practice what is likely to happen is that a stream of characters will be printed out by treating the memory starting from mychar as an array of char and iterating over it, until a \0 is found.
If you want to print the address, you can cast the pointer to something that isn't char*:
std::cout << static_cast<void*>(mypointer) << std::endl;

Making strings by pointers

I have learned that a pointer points to a memory address so i can use it to alter the value set at that address. So like this:
int *pPointer = &iTuna;
pPointer here has the memory address of iTuna. So we can use pPointer to alter the value at iTuna. If I print pPointer the memory address gets printed and if I print *pPointer then the value at iTuna gets printed
Now see this program
char* pStr= "Hello !";
cout<< pStr << endl;
cout<< *pStr << endl;
system("PAUSE");
return 0;
There are a lot of stuff I don't understand here:
In "Hello !" Each letter is stored separately, and a pointer holds one memory address. So how does pStr point to all the letters.
Also When I print out pStr it prints Hello !, not a memory address.
And when I print out *pStr it prints out H only not all what pStr is pointing too.
I really can't understand and these are my concerns. I hope someone can explain to me how this works ad help me understand
"Hello !" is an array of type char const[8] and value { 'H', 'e', 'l', 'l', 'o', ' ', '!', 0 }. pStr is a pointer to its first element; its last element has the value 0.
There is an overload in the iostreams library for a char const * argument, which treats the ar­gu­ment as a pointer to the first element of an array and prints every element until it encounters a zero. ("Null-ter­mi­nat­ed string" in colloquial parlance.)
Dereferencing the pointer to the first element of an array gives you the first element of the array, i.e. 'H'. This identical to pStr[0].
1-) Since pStr points to a char, it actually points to the beginning of an array of a null terminated string
2-) cout is overloaded with a char * argument. It will print out ever character in the string until it reaches the null character
3-) You are dereferencing the pointer to the first element of the character array.
1-) In "Hello !" Each letter is stored seperatly, and a pointer holds
one memory adress. So how does pStr point to all the letters.
The letters are stored in that order in each memory cell with an extra final cell
holding 0 to mark the end.
2-)Also When i print out pStr it prints Hello ! not a memory adress.
The cout << understands that you are pointing at a string and so prints the string.
3-)And when i print out *pStr it prints out H only not all what pStr
is pointng too.
The * means you are askign for the value at that address. cout << knows that the address holds a char and so prints the char.
Your understanding of pointers is correct in all respects.
Your problem is that the << operator has been overridden for various datatypes on a stream. So the standard library writers have MADE the operator << do something specific on any variable of the type char * (in this case the something specific means output the characters at that address until you get to the end of string marker) as opposed to what you expect it to do (print an address in decimal or hex)
Similarly the << operator has been overridden for char to just output a single character, if you think about it for a bit you will realise that *pStr is a dereferenced pointer to a character - that is it is a char - thus it just prints a single char.
You need to understand concept of strings as well. In C and C++, string is a few characters (char's) located one after another in a memory, basically, 'H','e','l','l','o','\0'. Your pointer holds memory address of the first symbol, and your C++ library knows that a string is everything starting this address and ending with '\0'.
When you pass char* to cout, it knows you output a string, and prints it as a string.
Construction *pStr means "give me whatever is located at address stored in pStr". That would be char - a single character - 'H', which is then passed to cout, and you get only one character printed.
A pointer, *pStr points to a specific memory address, but that memory address can be used not only as a single element, i.e. a char, but also as the beginning of an array of such elements, or a block of memory.
char arrays are a special type of array in C in that some operations handle them in a specific way: as a string. Hence, printf("%s", ... and cout know that when given a char * they should look for a string, and print all the characters until the terminating null character. Furthermore, C provides a string library with functions designed to manipulate such char * as strings.
This behavior is just as you'd expect from your own analysis: de-referencing pStr simply gives you the value at the memory address, in this case the first element of an array of chars in memory.
A pointer to an array (a C style string is an array of char) is just a pointer to the first element of the array.
The << operator is overloaded for the type char* to treat it as a C-style string, so when you pass it a char* it starts at the pointer you give it and keeps adding 1 to it to find the next character until it finds the null character which signals the end of the string.
When you dereference the pointer you the type you get is char because the pointer only actually points to the first item in the array. The overload of << for char doesn't treat it as a string, just as a single character.
Using strings like this is C-style code. When using C++ you should instead use std::string. It is much easier to use.

How does printf display a string from a char*?

Consider a simple example
Eg: const char* letter = "hi how r u";
letter is a const character pointer, which points to the string "hi how r u". Now when i want to print the data or to access the data I should use *letter correct?
But in this situation, shouldn't I only have to use the address in the call to printf?
printf("%s",letter);
So why is this?
*letter is actually a character; it's the first character that letter points to. If you're operating on a whole string of characters, then by convention, functions will look at that character, and the next one, etc, until they see a zero ('\0') byte.
In general, if you have a pointer to a bunch of elements (i.e., an array), then the pointer points to the first element, and somehow any code operating on that bunch of elements needs to know how many there are. For char*, there's the zero convention; for other kinds of arrays, you often have to pass the length as another parameter.
Simply because printf has a signature like this: int printf(const char* format, ...); which means it is expecting pointer(s) to a char table, which it will internally dereference.
letter does not point to the string as a whole, but to the first character of the string, hence a char pointer.
When you dereference the pointer (with *) then you are referring to the first character of the string.
however a single character is much use to prinf (when print a string) so it instead takes the pointer to the first element and increments it's value printing out the dereference values until the null character is found '\0'.
As this is a C++ question it is also important to note that you should really store strings as the safe encapulated type std::string and you the type safe iostreams where possible:
std::string line="hi how r u";
std::cout << line << std::endl;
%s prints up to the first \0 see: http://msdn.microsoft.com/en-us/library/hf4y5e3w.aspx, %s is a character string format field, there is nothing strange going on here.
printf("%s") expect the address in order to go through the memory searching for NULL (\0) = end of string. In this case you say only letter. To printf("%c") would expect the value not the address: printf("%c", *letter);
printf takes pointers to data arrays as arguments. So, if you're displaying a string (a type of array) with %s or a number with %d, %e, %f, etc, always pass the variable name without the *. The variable name is the pointer to the first element of the array, and printf will print each element of the array by using simple pointer arithmetic according to the type (char is 1 or 2 bytes, ints are 4, etc) until it reaches an EOL or zero value.
Of course, if you make a pointer to the array variable, then you'd want to dereference that pointer with *. But that's more the exception than the rule. :)