The last 2 cout statements have the same size. why?
int main()
{
char ch=127;
cout<<sizeof(ch)<<endl; //Size=1
cout<<sizeof("Hello")<<endl; //Size=6
cout<<sizeof("Hello"+ch)<<endl; //Size=8
cout<<sizeof("HelloWorld"+ch)<<endl; //Size=8
return 0;
}
Please explain.
Thanks
When you do "Hello"+ch the array containing the string "Hello" decays to a pointer to its first element, and you add ch to this pointer.
The result of pointer arithmetic is a pointer, which is what you get the size of.
Equivalent code would be something like
char const hello[] = "Hello";
char const* phello = hello; // equivalent to &hello[0]
char const* result = phello + ch;
cout << sizeof(result) << endl;
Related
void reverse(char[] x) {
char* pStart = x;
char* pEnd = pStart + sizeof(x) - 2;
while(pStart < pEnd) {
char temp = *pStart;
*pStart = *pEnd;
*pEnd = temp;
pStart++;
pEnd--;
}
}
int main() {
char text[] = ['h','e','l','l','o'];
reverse(text);
cout << text << endl;
return 0;
}
I am new to C++ and stack overflow.
I am trying to reverse a string using pointers... I don't quite understand what I did wrong. Please help me out.
Additional question: What is the difference between a string and an array of characters?
sizeof(x) with x being a parameter of type char[] of a function does not give you the number of characters in the string but the size of a char*, probably 8 on a 64 bit system. You need to pass a C-String and use strlen(x) instead. Write char text[] = {'h','e','l','l','o','\0'} or char text[] = "hello" in main.
Note that sizeof() needs to be evaluatable at compile time; this is not possible on arrays with undetermined size like char[]-typed function arguments. When using sizeof on a variables like your char text[] = {'h','e','l','l','o'}, however, sizeof(text) will result in the actual size of the array.
char x[] is the same as char* x and the sizeof(x) is therefore the size of a pointer. So, because you cannot calculate the size of an array outside of the block it is declared in, I would eliminate that part from your function.
It would be much easier to provide the function with pointers to the first and last characters to be replaced:
void reverse(char* pStart, char* pEnd)
{
while (pStart < pEnd)
{
char temp = *pStart;
*pStart = *pEnd;
*pEnd = temp;
pStart++;
pEnd--;
}
}
So now it is quite easy to call this function - take the address (using ampersand &) of the the relevant characters in the array: &text[0] and &text[4].
To display an array of characters, there is a rule, that such "strings" HAVE to have after the last character a NULL character. A NULL character can be written as 0 or '\0'. That is why it has to be added to the array here.
int main()
{
// char text[] = "hello"; // Same like below, also adds 0 at end BUT !!!in read-only memory!!
char text[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
reverse(&text[0], &text[4]);
std::cout << text << std::endl;
return 0;
}
I am trying my best to return a pointer with a specific value. Though, I am not understanding why I am getting more chars than usual. I asked a few people and I was told that I am getting a substring?
Problem: I type in the word hotdog.
I expect to return a pointer at the index[2]. Though instead, I get the chars dog. Why is that? How would I get just index[2]? I am thinking about dereferencing it, but I am having problems in getting the return type to work.
I cannot change the return type or parameters for my function.
#include <iostream>
char * GetValueAtIndex(char * const c, int index);
void ReadString(char * c, int length);
int main()
{
const int size = 10;
char ma[size];
char * pointer = ma;
ReadString(ma, 20);
std::cout << GetValueAtIndex(pointer, 3) << std::endl;
system("pause");
}
void ReadString(char * c, int length)
{
std::cin.getline(c, length);
}
char * GetValueAtIndex(char * const c, int index)
{
return c + index;
}
Modify your function to return a value not a pointer:
char GetValueAtIndex(char * const c, int index){
return *(c + index);
}
or simply dereference a pointer returned by a function:
std::cout << *GetValueAtIndex(pointer, 3);
When you have a char* pointer like:
char* p = "Hotdog";
and send that p to std::cout it will be treated as a pointer to (a first character of a) C style string and printed as such. C style strings end with \0. So it will print out whatever the character the p points to followed by all the remaining characters until it reaches the end of the string that is \0.
If you increment a pointer it then points at the next character etc:
char* p = "Hotdog";
p++;
std::cout << p;
p+=3;
std::cout << p;
If you just need to print a single character the p points at then send a dereferenced pointer to std::cout:
char* p = "Hotdog";
std::cout << *p;
Why do I return a series of a chars for a pointer return type?
You return a pointer to a character, exactly as you state what you're trying to do.
I expect to return a pointer at the index[2]
That pointer was returned, as you expected.
Though instead, I get the chars dog.
That is because you insert the pointer into a stream. The stream insertion operator for char* requires that the input is a pointer to a null terminated string and the behaviour is to print that entire string. Your pointer points to an array of chars starting from the character 'd'.
I am thinking about dereferencing it
If you dereference the pointer, you will get the character that is pointed to ('d'):
std::cout << *GetValueAtIndex(pointer, 3) << std::endl;
I my trying to copy a value into a char.
my char array is
char sms_phone_number[15];
By the way, could tell me if I should write (what the benefic/difference?)
char * sms_phone_number[15]
Below displays a string: "+417611142356"
splitedString[1]
And I want to give that value to sms_from_number
// strcpy(sms_from_number,splitedString[1]); // OP's statement
strcpy(sms_phone_number,splitedString[1]); // edit
I've got an error, I think because splitedString[1] is a String, isn't?
sim908_cooking:835: error: invalid conversion from 'char' to 'char*'
So how can I copy it correctely.
I also tried with sprintf without success.
many thank for your help.
Cheers
I declare spliedString like this
// SlitString
#define NBVALS 9
char *splitedString[NBVALS];
I have that function
splitString("toto,+345,titi",slitedString)
void splitString(char *ligne, char **splitedString)
{
char *p = ligne;
int i = 0;
splitedString[i++] = p;
while (*p) {
if (*p==',') {
*p++ = '\0';
if (i<NBVALS){
splitedString[i++] = p;
}
}
else
{
p++;
}
}
while(i<NBVALS){
splitedString[i++] = p;
}
}
If I do a for with splitedString display, it display this
for(int i=0;i<4;i++){
Serialprint(i);Serial.print(":");Serial.println(splitedString[i]);
}
//0:toto
//1:+4176112233
//2:14/09/19
I also declared and want to copy..
char sms_who[15];
char sms_phone_number[15];
char sms_data[15];
//and I want to copy
strcpy(sms_who,splitedString[0]
strcpy(sms_phone_number,splitedString[1]
strcpy(sms_date,splitedString[2]
I know, I am very confused with char and pointer * :o(
The declaration:
char * SplittedString[15];
Declares an array of pointers to characters, a.k.a. C-style strings.
Given:
const char phone1[] = "(555) 853-1212";
const char phone2[] = "(818) 161-0000";
const char phone3[] = "+01242648883";
You can assign them to your SplittedString array:
SplittedString[0] = phone1;
SplittedString[1] = phone2;
SplittedString[2] = phone3;
To help you a little more, the above assignments should be:
SplittedString[0] = &phone1[0];
SplittedString[1] = &phone2[0];
SplittedString[2] = &phone3[0];
By definition, the SplittedStrings array contains pointers to single characters, so the last set of assignments is the correct version.
If you are allowed, prefer std::string to char *, and std::vector to arrays.
What you need is a vector of strings:
std::vector<std::string> SplittedStrings(15);
Edit 1:
REMINDER: Allocate space for your spliedString.
Your spliedString should either be a pre-allocated array:
char spliedString[256];
or a dynamically allocated string:
char *spliedString = new char [256];
Strings and Chars can be confusing for noobs, especially if you've used other languages that can be more flexible.
char msg[40]; // creates an array 40 long that can contains characters
msg = 'a'; // this gives an error as 'a' is not 40 characters long
(void) strcpy(msg, "a"); // but is fine : "a"
(void) strcat(msg, "b"); // and this : "ab"
(void) sprintf(msg,"%s%c",msg, 'c'); // and this : "abc"
HTH
sorry for another string copy question.. but I really can't find the reason why in my code, strTo can be printed, but strFinal can't in neither way.
cout << strTo << endl;
cout << strFinal << endl;
while (*strFinal != '\0') {
cout << *strFinal++;
}
Appreciated if someone can point it out where I misunderstood about pointers and arrays! Thanks!
#include <iostream>
using namespace std;
char *str_copy (const char *strFrom, char *strTo)
{
while (*strFrom != '\0') {
*strTo++ = *strFrom++;
}
*strTo = '\0';
return strTo;
}
int main()
{
char strFrom[]="abc123";
char strTo[10];
char *strFinal = str_copy(strFrom, strTo);
cout << strTo << endl;
cout << strFinal << endl;
while (*strFinal != '\0') {
cout << *strFinal++;
}
return 0;
}
Additional Question:
I don't know the reason when I put the code in main function like this:
char strFrom[]="abc123";
char strTo[10];
strTo = str_copy(strFrom, strTo);
Then complier said:
main.cpp:18: error: array type 'char [10]' is not assignable
strTo = str_copy(strFrom, strTo);
~~~~~ ^
How should I correct in this way? Thanks!
The function returns a pointer to the terminating zero.
char *str_copy (const char *strFrom, char *strTo)
{
//...
*strTo = '\0';
return strTo;
}
Change it the following way
char *str_copy (const char *strFrom, char *strTo)
{
char *p = strTo;
while ( *p++ = *strFrom++ );
return strTo;
}
Also I would declare it the same way as standard C function strcpy is declared
char *str_copy( char *strTo, const char *strFrom );
As for your additional question then you may not assign a pointer or even other array to an array. So the compiler issues the error.
Arrays have no the assignment operator. You can only copy their elements.
Otherwise use standard class std::array.
After returning from str_copy you strTo does not point to the beginning of your copied string. In main strTo is ok, because it was passed by value (address of pointer after returning from str_copy is not changed even though you were using strTo++). But returned value of strFinal points to last character of copied string - '\0'.
For second part - char[10] has unchangeable addres, so you can't assign anything to variable of this type, like you tried in strTo = str_copy(...);.
Your second question : you are trying to assing char[10] with char* which is not possible
&strTo[0] = str_copy(strFrom, strTo);
But it's not usefull since the copy is done inside
In ur code, after calling str_copy() function:
char *strFinal = str_copy(strFrom, strTo);
strFinal points to the '\0', which is at the end of "abc123".
strTo in main() function can display correctly, because it is not THE SAME strTo
in str_copy() function, but points to strTo[10]. strTo in str_copy() still points to the terminating zero.
I have a homework, It is:
Write the code of function below, this function should count number of bytes inside of s till it is not '\0'.
The function:
unsigned len(const char* s);
Really I do not know what this homework mean, can anyone write this homework's code please?
Further more can anyone please explain what does "Const char* s" mean? If you can explain with some examples it would be perfect.
Here is a code which I'm trying to do:
unsigned len(const char* s)
{
int count=0;; int i=0;
while (*(s+i)!=0)
{
count++;
i++;
}
return count;
}
But in the main function I do not know what should I write, BTW I have written this:
const char k='m';
const char* s=&k;
cout << len(s) << endl;
The result always is 4! really I do not know what should I do for this question, if I can store only one character in const char, so the result should be the same always. What this question is looking for exactly?
The homework means you should write a function that behaves like this:
int main() {
char s[] = {'a','b','c','\0'};
unsigned s_length = len(s);
// s_length will be equal to 3 ('a','b','c', not counting '\0')
}
I think it's unlikely that anyone will do you homework for you here.
Presumably your class has covered function parameters, pointers, and arrays if you're being asked to do this. So I guess you're asking about const. const char* s means that s points to a const char, which means you're not allowed to modify the char. That is, the following is illegal:
unsigned len(const char *s) {
*s = 'a'; // error, modifying a const char.
}
Here are the basic things you need to know about pointers to write the function. First, in this case the pointer is pointing at an element in an array. That is:
char A[] = {'a','b','c','\0'};
char const *s = &A[0]; // s = the address of A[0];
The pointer points to, or references, a char. To get that char you dereference the pointer:
char c = *s;
// c is now equal to A[0]
Because s points at an element of an array, you can add to and subtract from the pointer to access other elements of the array:
const char *t = s+1; // t points to the element after the one s points to.
char d = *t; // d equals A[1] (because s points to A[0])
You can also use the array index operator:
char c = s[0]; // c == A[0]
c = s[1]; // c == A[1]
c = s[2]; // c == A[2]
What would you used to look at each element of the array sequentially, with an increasing index?
Your proposed solution looks like it should work correctly. The reason you're getting a result of 4 is just coincidence. You could be getting any results at all. The problem with the way you're calling the function:
const char k='m';
const char* s=&k;
cout << len(s) << endl;
is that there's no '\0' guaranteed to be at the end. You need to make an array where one of the elements is 0:
const char k[] = { 1,2,3,0};
const char* s = &k[0];
cout << len(s) << '\n'; // prints 3
char m[] = { 'a', 'b', 'c', 'd', '\0', 'e', 'f'};
cout << len(m) << '\n'; // prints 4
char const *j = "Hello"; // automatically inserts a '\0' at the end
cout << len(j) << '\n'; // prints 5
In C (and by extension C++), strings can be represented as a sequence of characters terminated by a null character. So, the string "abc" would be represented as
'a', 'b', 'c', '\0'
This means, you can get the length of a C string by counting each character until you encounter a null. So if you have a null terminated const char* string, you can find out the length of that string by looping over the string and incrementing a counter variable until you find the '\0' character.
it means you have a string like hello world Every string terminates with a \0. That means it looks like this: hello world\0
Now step over the char array (char* s) until you find \0.
Update:
\0 is in fact only one single character of value 0x00. \ is used to tell visualize that this is meant instead of the number 0 in a string.
Example:
0abc\0 -> string starting with number 0 and is terminated with 0x0.
EDIT
char * indicates the type of the variable s. It is a pointer to a character array. const means that this character array is readonly and can't be changed.
Do you actually mean "count the characters till you find a '\0'"?
If so, you could implement it like this:
for each character
if it is not 0
increment x (where x is variable holding number of characters found)
otherwise
stop looking
return x
I am not going to write your homework as well :P, but let me give you some hint: it's called "pointer arithmetic". So, a pointer is a thing exactly just as it names says: a pointer to a memory "cell". As you know all variables in the memory are stored in "cells", that you can refer by an address. A C string is stored in continuous cells in the memory, so for example "abc" would look like something like (the '\0' is added by the compiler when you define a string literal with quotes):
+----+----+----+----+
|'a' |'b' |'c' |'\0'|
+----+----+----+----+
^
s
and you also get the address of the first char. Now, to get the address of 'b', you can simple add one to s like this: (s + 1). To get what is actually in the cell where s points to, you should use the * operator:
*s = 'a' or *(s + 1) = 'b'. This is called pointer arithmetic.
Note: in this case adding one to the pointer shifts to the next cell, because char is one byte long. If you define a pointer to bigger structure (long int for example of 4 bytes) adding one will move to the to the position in the memory where your next structure would begin (in case of long int it will move +4 bytes).
Now that should be enough help to finish your hw.
OK , I have found my answer, just check if I'm true:
#include <iostream>
using namespace std;
unsigned len(const char*);
int main()
{
const char* s = "Hello";
cout << len(s) << endl;
return 0;
}
unsigned len(const char* s)
{
int count=0;; int i=0;
while (*(s+i)!=0)
{
count++;
i++;
}
return count;
}
So it is showing that I have set "Hello" into const char* s; So for const char* variables I should use strings like "Hello" with the sign ("). Is that True?