This question already has answers here:
How to get the number of characters in a std::string?
(12 answers)
C sizeof char pointer
(5 answers)
Closed 9 years ago.
char* string = "hello there";
cout << sizeof( string ); // prints 4, which is the size of pointer
cout << sizeof( *string ); // prints 1, which is the size of char
How do I get the number of characters contained in the string (11)?
It's strlen you want for that, not sizeof. The first counts the number of characters up to the terminating NUL while the second gives you the size of the type which, in this case, is a pointer rather than the underlying array of characters.
By that last point, I mean:
char *x = "hello there";
char y[] = "hello there";
std::cout << sizeof(x) << ' ' << sizeof(y) << '\n';
will most likely output something like:
4 12
on a system with 32-bit pointers (and 8-bit char). In that case, the 4 is the size of the pointer, the 12 is the number of bytes in the array (including the NUL at the end).
In any case, that's moot, since strlen() is the right way to get the length of a C string (yes, even in C++, though you may want to consider using the C++ strings since they may save you a lot of trouble).
The function sizeof() returns the size of a data type in Byte
For example because you define:
char* string = "hello there";
then type of string is char * and size of mostly all pointer is 4 Bytes ( this function returns 4) But type of *string is char and size of every character is 1 Byte ( This function returns 1)
Solution for you :
Alternative 1:
Use function strlen() in library 'string.h'
Alternative 2:(from scratch)
int length = 0;
int index = 0;
while ( string[index] != '\0')
{
length++;
index++;
}
Related
This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Why does cout print char arrays differently from other arrays?
(4 answers)
How does std::cout work with char pointers?
(1 answer)
Closed last month.
I can't understand why cout prints DATA for str variable. str does not contain the memory address of the first caracter ? What does it mean DATA ?
#include<bits/stdc++.h>
using namespace std;
int main()
{
char str[7]=”DATA”;
cout << str[2]<<” “<<str;
return 0;
}
It prints T DATA.
Thank you for your help,
operator<< has an overload for const char* that prints out characters until it hits a null terminating character. And a char[] array decays into a char* pointer to its 1st element.
So, when we print str[2] it just prints the single character T, but when we print str it prints all of the characters.
str[2] is a single char, T, which you see.
str, on the other hand, is a char* (read: pointer to char), and cout will print it as a c-string - i.e., print all the characters until it reaches the null character (\0), similar to what printf would have done. If you don't want that overload, you could cast it to a void*:
cout << str[2] << " " << (void* ) str;
The following code
#include <iostream>
using namespace std;
int main()
{
const char* const foo = "f";
const char bar[] = "b";
cout << "sizeof(string literal) = " << sizeof( "f" ) << endl;
cout << "sizeof(const char* const) = " << sizeof( foo ) << endl;
cout << "sizeof(const char[]) = " << sizeof( bar ) << endl;
}
outputs
sizeof(string literal) = 2
sizeof(const char* const) = 4
sizeof(const char[]) = 2
on a 32bit OS, compiled with GCC.
Why does sizeof calculate the length of (the space needed for) the string literal ?
Does the string literal have a different type (from char* or char[]) when given to sizeof ?
sizeof("f") must return 2, one for the 'f' and one for the terminating '\0'.
sizeof(foo) returns 4 on a 32-bit machine and 8 on a 64-bit machine because foo is a pointer.
sizeof(bar) returns 2 because bar is an array of two characters, the 'b' and the terminating '\0'.
The string literal has the type 'array of size N of const char' where N includes the terminal null.
Remember, arrays do not decay to pointers when passed to sizeof.
sizeof returns the size in bytes of its operand. That should answer question number 1. ;) Also, a string literal is of type "array to n const char" when passed to sizeof.
Your test cases, one by one:
"f" is a string literal consisting of
two characters, the character f and the terminating
NUL.
foo is a pointer (edit: regardless of qualifiers), and pointers seem to be 4 bytes long on your system..
For bar the case is the same as "f".
Hope that helps.
This question already has answers here:
Why is address of char data not displayed?
(8 answers)
Closed 6 years ago.
I'm going through the basics of learning C++, but keep hitting a wall when trying to decipher the following about chars and pointers. Included are line comments giving my current understanding of what's going on. Given that I have code like below:
using namespace std;
int main()
{
//String literal is an array of chars
//Array address gets assigned to a ptr of char
char myletters[] = {'h','i'};
char* lp = myletters;
cout << *lp << endl;
//Logically equivalent to above statements
char* letters2 = "hi";
cout << *letters2 << endl;
//String literal turns into array of chars
//Array of chars gets assigned to a ptr of chars
//Each ptr of chars gets stored into letters array
char* letters[] = {"hi","hello"};
cout << *letters << endl;
}
My output will be:
h
h
hi
My question is: when I use the final cout to print the contents of *letters, why do I get the string "hi" rather than the address of "hi" or the address of the first character in "hi"? I get that the first uses of cout are printing a char, and that the last cout is printing a char*, but I'm still wondering why it prints the complete string rather than the address as I would generally expect from a pointer.
Thanks kindly.
the << operator has a special definition for char* that prints the C-string it refers.
In your case, *letters has char* type (being letters a char*[], same as char**) and not char as *lp have.
When I run the code below my output is not what I expect.
My way of understanding it is that ptr points to the address of the first element of the Str array. I think ptr + 5 should lead to the + 5th element which is f. So the output should only display f and not both fg.
Why is it showing fg? Does it have to do with how cout displays an array?
#include <iostream>
using namespace std;
int main()
{
char *ptr;
char Str[] = "abcdefg";
ptr = Str;
ptr += 5;
cout << ptr;
return 0;
}
Expected output: f
Actual output: fg
When you declare:
char Str[] = "abcdefg"
The string abcdefg is stored implicitly with an extra character \0 which marks the end of the string.
So, when you cout a char* the output will be all the characters stored where the char * points and all the characters stored in consecutive memory locations after the char* until a \0 character is encountered at one of the memory locations! Since, \0 character is after g in your example hence 2 characters are printed.
In case you only want to print the current character, you shall do this ::
cout << *ptr;
Why is it showing fg?
The reason why std::cout << char* prints the string till the end instead of a single char of the string is , because std::cout treats a char * as a pointer to the first character of a C-style string and prints it as such.1
Your array:
char Str[] = "abcdefg";
gets implicitly assigned an '\0'at the end and it is treated as a C-style string.
Does it have to do with how std::cout displays an array?
This has to do with how std::cout handles C-style strings, to test this change the array type to int and see the difference, i.e. it will print a single element.
1. This is because in C there are no string types and strings are manipulated through pointers of type char, indicating the beginning and termination character: '\0', indicating the end.
I am currently trying to learn C++ from a book that I got from a friend of mine a couple of days ago. I I've seen some codes as a quiz in the book that I need to solve. So I tried to solve them but I'm not sure if my assumption is right.
This is the first one
char* r(char *g){ // can someone explain this line for me? I'm not sure what is it saying
char ch = 'B'; // is the code going to be correct if I changed char ch to char* ch?
return &ch; // since this is &ch, then the previous line should be char* ch, am I right?
}
The second code:
char* a;
a = new char[strlen(b)]; // will this line cause a compiling error just because b is undefined ? since there is no length for b because it's not even there?
strcpy(a,b); // since we're using strcpy() a and b has to be pointers am I right?
I am not asking for the answers, I need someone to tell me whether am right or wrong and why please.
char* r(char *g){ // can someone explain this line for me? I'm not sure what is it saying
Declares a function, r which takes one argument, a pointer g to contain the address of one or more characters.
char ch = 'B';
Declares a variable, ch of type char and assigns it a value 'B'. That is - it will contain a number which is the position in the ASCII chart of the letter B. It's going to contain the number 66, but when you print it out, it will produce the letter 'B'. (see http://www.asciitable.com/)
This variable will likely be on the stack. It could be in a register, but compilers are generally smart and the next line will ensure it is on the stack.
return &ch;
In this context, & is the address of operator.
return address_of(ch);
Since ch is of type char, &ch produces a value which is of type char*.
char* a;
Declares a variable a with no initial value. This is a bad thing to get into the habbit of writing.
a = new char[strlen(b)];
You say that b doesn't exist, but I think it's assumed to be of type char* - a pointer to one or more characters. In C and C++ a "C-String" is an array of 'char' values (characters) terminated by a char of value 0 (not the character '0', which has an ASCII value of 48, but 0, or '\0'). This is called a 'terminating nul' or a 'nul character' or a 'nul byte'.
The string "hello" is actually representable as an array { 'h', 'e', 'l', 'l', 'o', 0 }. Contrast with "hell0", which would be { 'h', 'e', 'l', 'l', '0', 0 };
The function strlen counts the number of characters from the address it is called with until it finds a nul. If b was the address of "hello", strlen would return 5.
new allocates memory for an object, or in this case an array of objects of type char, the number of which is the return value of strlen.
size_t len = strlen(b);
char* a = new char[len];
At this point in the code, recall my explanation about terminating nul and that strlen returns the number of characters before it finds the 0. To store a C-string you need the number of characters PLUS space for a terminating NULL.
If b is the string "A", it consists one character ('A') but two *char*s - 'A', and 0. Strlen returns the number of characters.
strcpy(a, b);
This will copy the characters pointed to by b to the address at a, *including the terminating nul.
The bug here is that you only allocated enough memory for the characters.
char* a = new char[strlen(b) + 1];
strcpy(a, b);
Again - strlen is always going to return the length - the number of characters, and you're always going to want one more than that, for the nul.
would be correct - otherwise you're going to overwrite the memory allocated to you and cause a corruption.
--- EDIT ---
Throwing some of this together, live demo here: http://ideone.com/X8HPxP
#include
#include
int main() {
char a[] = "hello";
std::cout << "a starts out as [" << a << "]\n";
// C/C++ arrays are 0-based, that is:
a[0] = 'H'; // changes a to "Hello"
std::cout << "a is now [" << a << "]\n";
std::cout << "strlen(a) returns " << strlen(a) << "\n";
// But that is based on counting characters until the 0.
a[3] = 0; // one way to write it,
a[3] = '\0'; // some people prefer writing it this way.
std::cout << "a changed to [" << a << "]\n";
std::cout << "strlen(a) is now " << strlen(a) << "\n";
return 0;
}
First Code:
r is function name having return type char* i.e. reference type and accepting parameter of reference type char* g.
'B' is assigned to ch variable.
r function returns the address of ch variable.
According to me no correction required in First code.
Second Code:
Yes it will cause compilation error at line 2 as b is not declared or defined.
1st Code:
You are defining a function called r which accepts a pointer to a char and returns a pointer to a char.
char* r(char *g){
//stack char variable ch is initialized to B
//changing char ch to char *ch will compile (with a warning) but then the address pointed by ch will contain garbage (value of 'B' projected as an address).
char ch = 'B';
//you are returning the address of ch which as seen above is a stack variable so you are causing undefined behavior. You should avoid this.
return &ch;
}
2nd Code:
char* a;
// if b is undefined as you state then following line will cause compiling error. strlen() will calculate the length of the area at runtime so b must be at lease defined first.
a = new char[strlen(b)];
//a is a pointer as you defined it above and points to the heap memory allocated by new
strcpy(a,b);
char* r(char *g){
here r() is function which take char* as argument and return char*
char ch = 'B';
return &ch;
Here, ch is char locally defined and you are returning it. This is not good. Better use char*. Also char will have only one character whereas if you use char* you can have more than one.
char* ch = "Thats My string";
return ch; //Notice ch is a pointer. No need to use &
Second Code:
char* a;
a = new char[strlen(b)];
If b is undefined, sure there will be error. If b is char* with some value assigned to it strlen will provide you length of string which b is having. so this looks good.
strcpy(a,b); // since we're using strcpy() a and b has to be pointers am I right?
Yes you are right! You can use strncpy instead.