#include <iostream>
using namespace std;
char* input(char **S);
int main()
{
char **S = new char *;
char *K = input(S);
//cout << K << endl;
cout << *K << endl;
}
char* input(char **S)
{
cout << "Enter string: ";
cin >> *S;
cout << S << endl; // Prints address of S
cout << *S << endl; //Prints content of address stored in S
return *S;
}
I am failing to understand why when I print out *K, I just get the first character of the input string but if I print out the commented line(just K alone) I get the whole string. Any help with explaining what I am not able to see or understand is appreciated.
Let's understand how arrays work:
// Let's say I have one character array
char arr[] = {'a', 'b', 'c', 'd'};
In here, the name of the array i.e. arr acts as the pointer to the first element of the array. However, do note that it is NOT the pointer to the first element to avoid confusion, it just have an implicit conversion to pointer of element type. More details can be found here: https://stackoverflow.com/a/1641963/10821123
Now since array is contiguous, the rest of the elements can be determined.
// so ideally, the below two statements would print the same thing
cout << &arr << endl;
cout << (void*) &arr[0] << endl;
// the above line just takes out the address of the first pointer
Now coming to your question, I'll convert my example to a string one:
char *K = "abc";
cout << *K << endl; // a
cout << K << endl; // abc
Note that the above assignment of char *K = "abc"; will give you a warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
The pointer only holds the address of the first element of the array, so when you dereference the pointer, it prints the first element, i.e. *K is interpreted as K[0]
Now there's an overload of operator <<, so what it does is if it sees a character pointer i.e. char*, it prints the complete null-terminated string, that's why in your case too, it is printing the whole string.
Related
I am trying to convert an integer to a char pointer as shown below. The data results are different. I am not sure what is going wrong. Please help me in correcting the code.
int main(){
char *key1 = "/introduction";
std::ostringstream str1;
str1<< 10;
std::string data=str1.str();
std::cout <<"The data value="<<data<<std::endl; // The data value= 10
char *intro= new char[data.length()+1];
strcpy(intro, data.c_str());
std::cout <<"The data value="<<*intro <<std::endl; // The data value=1
return 0;
}
I am not sure why two data value are printed different i.e, 10 and 1.
In C++, when trying to print all the contents of a char * with cout, you should pass the pointer, i.e. cout << intro << endl.
What you've done here is dereferenced the char *, so cout << *intro << endl is equivalent to cout << intro[0] << endl, which is equivalent to printing the first character, 1.
I have not used c++ for a long while so maybe I forget some very simple trick. Here is the code and I tried to print the content of *p and got nothing printed out.
#include <iostream>
using namespace std;
int main() {
char hello[] = "hello";
char *p = hello;
while (*p) {
*p += 1; // increase the character by one
p += 1; // move to the next spot
}
cout << "content of hello is: " << hello << endl;
cout << "content of hello is: " << *p << endl;
return 0;
}
Good thing is I figured out by myself while writing this question. The reason is very simple: p is a pointer type for char, and the p is altered in the while loop. So this will print out i:
cout << "content of hello is: " << *(p - 5) << endl;
Just note it here.
C-strings, which you're dealing with here, are terminated by a null character ('\0'). That's why looping while *p is true works. When p points to a null terminator, dereferencing it gives us 0, which is false.
Your loop increments p until it points to the null terminator. That means at the conclusion of the loop, it must be pointing to '\0' which counts as an empty C-string. Your program then prints that empty string.
As a beginner of learning C++, I am trying to understand the difference between an array of type char and an array of type int. Here is my code:
void IntArray () {
int array[5] = {5,6,7,8,9};
cout << "Print int array: " << array << endl;
cout << "Print int array[0]: " << array[0] << endl;
cout << "Print int array[0]+1: " << array[0]+1 << endl;
}
void CharArray () {
char array[5] = {'a', 'b', 'c', 'd', '\0'};
cout << "Print char array: " << array << endl;
cout << "Print char array[0]: " << array[0] << endl;
cout << "Print char array[0]+1: " << array[0]+1 << endl;
}
And here is the output:
Print int array: 0xbfd66a88
Print int array[0]: 5
Print int array[0]+1: 6
Print char array: abcd
Print char array[0]: a
Print char array[0]+1: 98
My questions are:
Why does the following output the string '0xbfd66a88'? I was expecting it to return the address of the first element in the array:
cout << "Print char array: " << array << endl;
Why does the following output '98'? I was expecting it to output the letter 'b':
cout << "Print char array[0]+1: " << array[0]+1 << endl;
1.
Because char arrays are treated differently to other arrays when you stream them to cout - the << operator is overloaded for const char*. This is for compatibility with C, so that null-terminated char arrays are treated as strings.
See this question.
2.
This is due to integral promotion. When you call the binary + with a char (with value 'a') and an int (with value 1), the compiler promotes your char to either a signed int or an unsigned int. Which one is implementation specific - it depends on whether char is signed or unsigned by default, and which int can take the full range of char. So, the + operator is called with the values '97' and '1', and it returns the value '98'. To print that as a char, you need to first cast it:
cout << "Print char array[0]+1: " << static_cast<char>(array[0]+1) << endl;
See this question.
Okay let's go over each separately.
Print int array: 0xbfd66a88
Here you print an int[] which goes into the operator << overload that takes int*. And when you print a pointer you see a memory address in hexadecimal format.
Print int array[0]: 5
Here you print the first element of the array which is an int. As expected.
Print int array[0]+1: 6
Here you add 1 to the first element of the array and print the result, which is still an int. 5+1 becomes 6. No mystery here.
Print char array: abcd
This is a bit trickier. You print a char[] and there is a special overload for operator << that takes a const char* and that one gets called. What this overload does is print each character beginning from the address where the pointer points until it finds a terminating zero.
Print char array[0]: a
Here you print a char so the overload that takes char gets called. It prints the corresponding ASCII character, which is 'a'.
Print char array[0]+1: 98
Here the result of operator+ is an int because the literal 1 is an int and the char value gets promoted to the wider type (int). The result is 98 because the ASCII code of the letter 'a' is 97. When you print this int you just see the number.
This question already has answers here:
Why does cout print char arrays differently from other arrays?
(4 answers)
Closed 7 years ago.
Perhaps a stupid question. When I cout the pointer to the char array, I thought it would print an address; instead it dereferences the address and prints the actual values till null.
As opposed to an int array where it does what I expect it to. It prints the address of the first element.
Why does the char element gets dereferenced when you print the pointer.
char* as = new char[100];
as[0] = 'a';
as[1] = 'b';
as[2] = NULL;
cout << as << endl;
int* s = new int[100];
s[0] = 2;
cout << s << endl;
Asking this because when I try to get the address to the first char element a[0] = 'a';. I have to store it in a pointer to a pointer. Which seems weird to me but that's besides the point.
char ** d = &as;
cout << d << "this is d" << endl;
There is no overloaded output operator << that prints the address for any char pointer, it treats all char pointers as strings. If you want to print the address of a pointer, you need to cast it to void*
std::cout << "Address of string is " << static_cast<void*>(as) << '\n';
On a side-note, the code
char ** d = &as;
cout << d << "this is d" << endl;
will not print the address of the string, i.e. the pointer contained inside as, instead it will print where the variable as is stored in memory. Not quite the same thing.
char* character pointers are considered to be C-style null terminated strings by the std::ostream << operator. You are right that this is a different behavior from other pointer types.
&a is not a pointer to a[0] . It is a pointer to a which is itself a pointer. a is in fact the pointer to a[0] and is equivalent to &a[0].
IOStreams treat char* (and const char*) specially, so that you can print C-strings without further effort:
std::cout << "hello world\n";
(Bear in mind that the string literal expression decays immediately to a const char* when passed to operator<<.)
If you do not want this behaviour, you can cast to void*:
char* as = new char[100];
as[0] = 'a';
as[1] = 'b';
as[2] = NULL;
cout << (void*)as << endl;
Your "fix" is actually broken, because you are printing the address of the pointer as, not the address of the array elements that as points to. This is indicated by the char** type, which you already noticed.
It prints the string because that's what the definition of that particular operator<< overload does. Cast to void * if you want to print an address:
cout << static_cast<void *>(as) << endl;
The << operator is overloaded to take a char* and output its contents where as there is no such overload for a int*/int[].
I've written this simple script to understand what a reference is, and I'm getting stuck on the char array.
int numbers[5] = {3, 6, 9, 12, 15};
for (int i = 0; i < 5; i++)
{
cout << numbers[i] << endl;
cout << &numbers[i] << endl;
}
cout << "--------------" << endl;
char letters[5] = {'a', 'b', 'c', 'd', 'e'};
for (int i = 0; i < 5; i++)
{
cout << letters[i] << endl;
cout << &letters[i] << endl;
}
and this is the output:
3
0xbffff958
6
0xbffff95c
9
0xbffff960
12
0xbffff964
15
0xbffff968
--------------
a
abcde
b
bcde
c
cde
d
de
e
With the int array, when I use &numbers[i], I receive a strange number that is a memory location. This is ok; it's exactly what I've understood.
But with char, I don't understand why I have this output.
The reason is that cout "knows" what to do with a char * value - it prints the character string as a NUL-terminated C string.
The same is not true of an int * value, so cout prints the pointer value instead.
You can force pointer value output by casting:
cout << static_cast<void *>(&letters[i]) << endl;
You are looking at a peculiarity of C++ streams. It tries to convert its arguments to something that is usually printable. The type of this expression is &ints[x] int*. &chars[x] becomes char* which is, incidentally also the type of a C character string. As we want this cout << "FOO"' to print out the whole string, it is needed to have this behavior. In your case this actually results in undefined behavior as the string you are using is not properly null-terminated. To resolve this issue use a static_cast.
When you pass to ostream::operator<< (in fact it is a global function, not an operator) the argument of type char*, it is considered as a null-terminated string.