Script
#include <iostream>
using namespace std;
int main()
{
float nums[3];
nums[0]=1.5;
nums[1]=2.75;
nums[2]=3.25;
const char* name[5]={"m", "i", "k", "e", "\0"};
int coords[2][3]={{1, 2, 3}, {4, 5, 6}};
cout << "nums[0]: " << nums[0] << endl;
cout << "nums[1]: " << nums[1] << endl;
cout << "nums[2]: " << nums[2] << endl;
cout << "name[0]: " << name[0] << endl;
cout << "Text String: " << name << endl;
cout << "coords[0][2]: " << coords[0][2] << endl;
cout << "coords[1][1]: " << coords[1][1] << endl;
return 0;
}
Output:
nums[0]: 1.5
nums[1]: 2.75
nums[2]: 3.25
name[0]: m
Text String: 0xffffcbb0
coords[0][2]: 3
coords[1][1]: 5
Question:
How can I make the "Text String: " say "mike"
I tried char name[5],
I tried char* name[5];
Please help
Thank You
I'm new to c++, don't judge
const char* name[5]={"m", "i", "k", "e", "\0"};
Is an array of pointers to characters. You have unintentionally created an array of pointers to strings rather than a string.
cout of a pointer results in the address being printed, except in the case of a pointer to a character where the << operator has been written to assume a null-terminated c-style string.
To fix this, you can
1 Use a pointer to a string literal
const char* name="mike";
2 Use an array of characters
const char name[5]={'m', 'i', 'k', 'e', '\0'};
Or 3 use a combination of the two
const char name[5]="mike";
As an added bonus, because in the latter two cases the initialization implies the size of the array you can leave it out,
const char name[]="mike";
and the compiler will figure it out. Very handy when you change from "mike" to "henry" as you don't have to adjust the size.
When you are done this exercise, take some time and read up on std::string. Use it wherever possible instead of C-Style strings. It will save you an amazing amount of time, blood, and tears.
const char name[5]={'m', 'i', 'k', 'e', '\0'};
What you need is an array of chars.
Character literals are written using single quotes ('). If you use double quotes ("), you get a string literal instead.
Using your notation, change the double quotes to single quotes and get rid of the asterisk.:
const char name[5]={'m', 'i', 'k', 'e', '\0'};
Or you could use:
const char name[] = "mike";
Related
This question already has answers here:
Why is address of char data not displayed?
(8 answers)
print address of array of char
(3 answers)
C++ pointer assigning char array's address
(2 answers)
How do I get the address of elements in a char array?
(2 answers)
Closed 2 years ago.
I just started learning C++. I have confusion while printing out the int array it is printing the 0th element address of the array. And (array + 1) is the address after 4 registers since int is 4byte. But for char array, the behavior is not the same. Is char array implemented differently in C++?
code:
#include <iostream>
using namespace std;
int main()
{
char char_array [5] {'a', 'e', 'i', 'o', 'u'};
int int_array [5] {1,2,3,4,5};
cout << sizeof(char) << endl;
cout << sizeof(int) << endl;
cout << char_array << endl;
cout << char_array+1 << endl;
cout << int_array << endl;
cout << int_array + 1 << endl;
}
output:
1
4
aeiou≡r
eiou≡r
0x61fe00
0x61fe04
Process returned 0 (0x0) execution time : 0.428 s
Press any key to continue.
For starters the program has undefined behavior because the declared character array
char char_array [5] {'a', 'e', 'i', 'o', 'u'};
does not contain a string but using the overloaded operator << in these statements
cout << char_array << endl;
cout << char_array+1 << endl
for a pointer to char requires that the pointer would point to a string.
You could at least declare the array like
char char_array [6] {'a', 'e', 'i', 'o', 'u', '\0' };
Using an integer array as an expression in the operator << results that the overloaded resolution selects the operator for the type void * and the operator outputs the address of the first element of the integer array.
In these statements
cout << char_array+1 << endl;
cout << int_array + 1 << endl;
there is used the pointer arithmetic. The expression char_array+1 or int_array + 1 increases the value or the pointer (the array designator in such an expression is implicitly converted to pointer to its first element) by the value equal to sizeof( char ) or sizeof( int ) correspondingly.
sizeof( char ) is always equal to 1. sizeof( int ) depends on the used system and usually at least for 32-bit systems is equal to 4. And this output
0x61fe00
0x61fe04
demonstrates this.
If you want to output addresses for elements of the character array then you should write for example
cout << static_cast<void *>( char_array ) << endl;
cout << static_cast<void *>( char_array+1 ) << endl;
char[5] gets decayed to char const *, and then there is an overload for operator<< that writes out the string represented by the char const *.
int[5] decays to int const *, but there is not a similar overload for int const *, and so it simply prints the address.
std::cout is a variable of type std::basic_ostream which has an overload especially for formatting char*. Which is important because raw arrays will decay to pointers when passed by value.
The unique overload of operator<< for char* expects that the incoming data is a C String. Which is a string of characters that is nul terminated.
char char_array [5] {'a', 'e', 'i', 'o', 'u'};
Creates an array which is not nul terminated which is why you get seemingly random characters (via a buffer over read, leading to undefined behaviour). To rectify that you would just need to include a nul terminator. When char_array is declared as :
char char_array [6] {'a', 'e', 'i', 'o', 'u','\0'};
then
std::cout << char_array << std::endl;
will output aeiou and
std::cout << char_array + 1 << std::endl;
will output eiou
Here int_array is a pointer to an array of int. When you print int_array, you are printing the address of the start of the array (0x61fe00 in you case). When you print int_array + 1 your are doing what is called pointer arithmetic: int_array + 1 could be roughly translated as give me the next address holding and int and as int is 4 bytes, you can see that the next address is effectively the address plus four.
char_array is also a pointer to an array of char. Passing a pointer to an array of char while effectively print the underlying string. Here your string misses the end character `\0' which is UB.
You should definitively read on what is a pointer and a value because it is clear here that you are missing that knowledge.
A char array is a string and is being output as one.
I was playing around with char arrays in c++ and wrote this program:
int main()
{
char text[] = { 'h', 'e', 'l', 'l', 'o' }; //arrays initialised like this
//will have a size of the number
//of elements that you see
char text2[] = "hello"; //arrays initialised like this will have a size of
//the number of elements that you see + 1 (0 on the
//end to show where the end is
cout << endl;
cout << "The size of the first array is: " << sizeof(text) << endl;
cout << endl;
for (int i = 0; i < sizeof(text); i++)
{
cout << i << ":" << text[i] << endl;
}
cout << endl;
cout << "The size of the first array is: " << sizeof(text2) << endl;
cout << endl;
for (int i = 0; i < sizeof(text2); i++)
{
cout << i << ":" << text2[i] << endl;
}
cout << endl;
cin.get();
return 0;
}
This program gives me the output:
The size of the first array is: 5
0:h
1:e
2:l
3:l
4:o
The size of the first array is: 6
0:h
1:e
2:l
3:l
4:o
5:
My question is: Is there a particular reason that initializing a char array with separate chars will not have a null terminator (0) on the end unlike initializing a char array with a string literal?
A curly braces initializer just provides the specified values for an array (or if the array is larger, the rest of the items are defaulted). It's not a string even if the items are char values. char is just the smallest integer type.
A string literal denotes a zero-terminated sequence of values.
That's all.
Informally, it's the second quotation character in a string literal of the form "foo" that adds the NUL-terminator.
In C++, "foo" is a const char[4] type, which decays to a const char* in certain situations.
It's just how the language works, that's all. And it's very useful since it dovetales nicely with all the standard library functions that model a string as a pointer to the first element in a NUL-terminated array of chars.
Splicing in an extra element with something like char text[] = { 'h', 'e', 'l', 'l', 'o' }; would be really annoying and it could introduce inconsistency into the language. Would you do the same thing for signed char, and unsigned char, for example? And what about int8_t?
A string literal like for example this "hello" has a type of a constant character array and initializwd the following way
const char string_literal_hello[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
As it is seen the type of the string literal is const char[6]. It contains six characters.
Thus this declaration
char text2[] = "hello";
that can be also written like
char text2[] = { "hello" };
in fact is substituted for the following declaration
char text2[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
That is then a string literal is used as an initializer of a character array all its characters are used to initialize the array.
You can terminate it yourself in multiple ways:
char text1[6] = { 'h', 'e', 'l', 'l', 'o' };
char text2[sizeof "hello"] = { 'h', 'e', 'l', 'l', 'o' };
char text3[] = "hello"; // <--- my personal favourite
Is there a particular reason that initializing a char array with separate chars will not have a null terminator (0)
The reason is because that syntax...
Type name[] = { comma separated list };
...is used for initializing arrays of any type. Not just char.
The "quoted string" syntax is shorthand for a very specific type of array that assumes a null terminator is desired.
When you designate a double quote delimited set of adjacent characters (a string literal), it is assumed that what you want is a string. And a string in C means an array of characters that is null-terminated, because that's what the functions that operate on strings (printf, strcpy, etc...) expect. So the compiler automatically adds that null terminator for you.
When you provide a brace delimited, comma separated list of single quote delimited characters, it is assumed that you don't want a string, but you want an array of the exact characters you specified. So no null terminator is added.
C++ inherits this behavior.
I have troubles understanding strings as pointers. Apparently a string is understood as a pointer which points to the first address of the string. So using the "&"-operator I should receive the address of the first character of the string. Here's a small example:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(){
char text[101];
int length;
cout << "Enter a word: ";
cin >> text;
length = strlen(text);
for (int i = 0; i <= length; i++) {
cout << " " << &text[i];
}
return 0;
}
When entering a word such as "Hello", the output is: "Hello ello llo lo o". Instead I expected to receive the address of each character of "Hello". When I use the cast long(&text[i]) it works out fine. But I don't understand why. Without the cast, apparently the "&"-operator gives the starting address of the string to be printed. Using a cast it gives the address of every character separately.
Maybe sb. can explain this to me - I'd be really grateful!
&text[i] is equivalent to text + i and that shifts the pointer along the char[] array by i places using pointer arithmetic. The effect is to start the cout on the (i)th character, with the overload of << to a const char* called. That outputs all characters from the starting point up to the NUL-terminator.
text[i] however is a char type, and the overload of << to a char is called. That outputs a single character.
In C++, if you want a string, then use std::string instead. You can still write cin >> text; if text is a std::string type! Your code is also then not vulnerable to overrunning your char buffer.
If you have a character array storing a string as for example
char text[] = "Hello";
then the array is initialized like
char text[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
In this statement
std::cout << text;
there is used operator << overloaded for the type const char * and the array text is converted implicitly to pointer to its first element.
You could write instead
std::cout << &text[0];
because in the both statements the expressions text and &text[0] have type char *.
The operator overloaded for the type const char * outputs characters starting from the address at the pointer until a zero character is encountered.
So if instead of the statement
std::cout << &text[0];
you'll write
std::cout << &text[1];
then the only thing that is changed is the starting address of the string and nothing more. That is in fact you are outputting string that is represented like
{ 'e', 'l', 'l', 'o', '\0' }
If to write
std::cout << &text[2];
that is if the pointer in the right side of the expression is moved one position right then it means that you'll deal with the string
{ 'l', 'l', 'o', '\0' }
and so on.
That is the operator << overloaded like
template<class traits>
basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&,
const char*);
just outputs entities pointed to by the second parameter as strings.
If you want to output the value of the pointer itself instead of the string pointed to by the pointer you should use another overloaded operator << declared like
basic_ostream<charT, traits>& operator<<(const void* p);
Tp invoke it you should write for example
std::cout << ( void * )text;
or
std::cout << ( void * )&text[i];
where i is some index.
Instead of the C casting you can use C++ casting like
std::cout << static_cast<void *>( &text[i] );
To print the address of an array element, you could do:
cout << " " << (void*)&text[i];
This:
cout << " " << &text[i];
is equivalent to this:
cout << " " << text + i;
which means that you ask to print the string, starting from index i.
I have come across a c++ code:
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
cout << "Greeting message: ";
cout << greeting << endl;
output: Hello
Since greeting is an array of size 6, displaying greeting should display only "H" because of greeting[0] in cout, since it is displaying first address of array. I don't know where I am wrong.
Except when it is the operand of the sizeof or unary & operators, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element of the array.
This means that in the statement
cout << greeting << endl;
the expression greeting is converted from an expression of type char [6] to an expression of type char *, and the value of the expression is the address of the first element.
The stream operator << is defined such that if it receives an argument of type char *, it will write out the sequence of characters starting at that address until it sees the 0 terminator; here's a simplistic example of how it might work:
std::ostream& operator<<( std::ostream& s, char *p )
{
while (*p)
s.put( *p++ );
return s;
}
The real operator definition will be a bit more complex, but that's the basic idea.
If you want to print out just the first character of greeting, you must explicitly index or dereference it:
cout << greeting[0] << endl;
or
cout << *greeting << endl;
greeting decays to a pointer itself. But if it sounds complicated, you can look at it as a pointer to understand what cout does.
cout method prints characters starting from greeting[0] until \0.
If you want to see the address value write
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
cout << "Greeting message: ";
cout << (void*)greeting << endl;
// ^^^^^^^
The std::ostream& std::operator<<(std::ostream&, T type); provides specializations for the const char*, const char[] and char types.
yes greeting here is a pointer to first element in the array so if you do something like that :
cout << *greeting;
output will be H.
but in reality when you pass it to cout object it's smart enough to know that greeting is not just a pointer but it's more it's a string according to the internal implementation of operator overloading in handling .
so it's not a problem ,it's just cout can understand it.
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.