I am trying to convert one char variable to a const char variable but I have the below error . Content of variable char is ok, in this case is a "H" and "e" but when I convert to const char* I have the letter + something else after. Can you guys please tell me where I did something wrong ?
Please see the picture from link !
#include <iostream>
#include <Windows.h>
#include <lmcons.h>
#include <stdio.h>
#include <stdlib.h>
char Body[] = { 'H', 'e', 'l', 'l', 'o' }; // elements of char array
int size = sizeof(Body); // get size of Body array
char Line;
std::cout << "Size : " << size << "\n"; // view the size of Body array
for(int i=0; i<=size; i++) // for statement : from first element to the last element of array
{ // beginning of for statement
Line = Body[i]; // get each element from Body array and put to char variable
std::cout << "Char : " << Line << "\n"; // view the content of char variable
const char *Line2 = &Line ; // convert from from char to const char*
std::cout << "Const char : " << Line2 << "\n"; // view the content of const char* variable
} // end of for statement
enter image description here
const char *Line2 = &Line ;
Doesn't magically create a string from your character; as a string must be Null (or 0) terminated you can't pass this pointer to cout as it's expecting multiple characters to be processed. If you were to change it to be
char Line[2] = {0}; // 0 initialise all the chars
Line[0] = Body[i];
Line[1] = 0; // completely not required, but just making the point
char* Line2 = &Line[0]; // there are other cleaner ways, but this shows explicitly what is happening
std::cout << Line2;
You would not have UB.
The problem is that you are not terminating Body with a null char(\0). And the second problem is your loop you are trying to access something that is out of range. The code should be like this:
char Body[] = { 'H', 'e', 'l', 'l', 'o', '\0' }; // elements of char array
int size = sizeof(Body); // get size of Body array
char Line;
std::cout << "Size : " << size << "\n"; // view the size of Body array
for(int i=0; i<size; i++) // for statement : from first element to the last element of array
{ // beginning of for statement
Line = Body[i]; // get each element from Body array and put to char variable
std::cout << "Char : " << Line << "\n"; // view the content of char variable
const char *Line2 = &Line ; // convert from from char to const char*
std::cout << "Const char : " << Line2 << "\n"; // view the content of const char* variable
} // end of for statement
You need null char at the end of the any raw string in c/c++ language because this helps it understand the ending of the string.
The problem is that you are accessing Body[5], when running the loop as
for(int t=0;t<=sizeof(Body);t++){}
if you remove that = sign it will be okay.
for(int t=0;t<sizeof(Body);t++){}
Also, try to convert
std::const char *Line2 = const_cast<const char *>(&Line );
Use std::const_cast<>() to convert non constant to constant data types.
Also to remove those extra things from console you need to dereference the const char *, if you directly use it. std::cout tries to print everything until null is encountered in case you pass it const char *
So,
std::cout << "Const char : " << *Line2;
Related
void reverse(char * str){
char * end = str;
cout << "str" << str << endl;//ABCDE
cout << "end" << end << endl;//ABCDE
char tmp;
if(str){
while(*end){++end; cout << end << endl;}//ABCDE-->BCDE-->CDE-->DE-->E--> NULL
--end;//end=E
cout <<"--end" << end << endl;
while(str<end){// do swap
tmp = *str;//*str = str[0]
*str++ = *end;//*end = last ele in str[]
*end-- = tmp;
}
}
}
My input is
char test[] = "ABCDE";
cout << test << endl; //ABCDE
reverse(test);
cout << test << endl; //EDCBA
I am feeling not good about the pointer, since c++ primer book says char* pointer to the first element of an array, but when I output the pointer end, it is the content of an array not the address.
Also, reverse(test), I mean to give the address of the first element in an array to the pointer, but it turns out give the whole elements to the pointer.
A char* variable is a pointer to a char. A char[] is an array of char. Now, an array of char can be accessed through a pointer, and for char* it is commonly used for string processing (it's used although for other types, but for char it's much more common).
char test[6] = "ABCDE";
char *start = &test[0]; // will point on A
Accessing the array with the pointer can be done with pointer arithmetic:
char *end = start + 5; // equivalent to char *end = &test[5]
Now when you do:
cout << test;
or
cout << start;
It's actually calling an overload of operator<< that takes a const char*. What this operator does is that it print char starting from the pointer passed until it reaches a null char ('\0').
If you want to print the address contained in the pointer and not the string, you have to cast it to void*:
cout << static_cast<void*>(start);
std::cout is overloaded to print strings for char* .
Try:
char *test = "ABCDE";
std::cout << (void *) test << std::endl;
I am trying to cout a const char *
This is how I convert an int to a string and concatenate it with the const char*
char tempTextResult[100];
const char * tempScore = std::to_string(6).c_str();
const char * tempText = "Score: ";
strcpy(tempTextResult, tempText);
strcat(tempTextResult, tempScore);
std::cout << tempTextResult;
The result when printing is: Score:
Does anyone know why the 6 is not printing?
Thanks in advance.
As the docs for c_str say, "The pointer returned may be invalidated by further calls to other member functions that modify the object." This includes the destructor.
const char * tempScore = std::to_string(6).c_str();
This makes tempScore point to a temporary string that no longer exists. You should do this:
std::string tempScore = std::to_string(6);
...
strcat(tempTextResult, tempScore.c_str());
Here, you're calling c_str on a string that continues to exist.
You have marked this post as C++.
One possible C++ approach: (not compiled, not tested)
std::string result; // empty string
{
std::stringstream ss;
ss << "Score: " // tempText literal
<< 6; // tempScore literal
// at this point, the values placed into tempTextResult
// are contained in ss
result = ss.str(); // because ss goes out of scope
}
// ss contents are gone
// ... many more lines of code
// ... now let us use that const char* captured via ss
std::cout << result.c_str() << std::endl;
// ^^^^^^^ - returns const char*
In C++ string literals "Hello" are const and are immutable. I wanted to make a custom string class whose strings are not const chars, so they can be changeable
Here is a snippet of code that might illustrate what I'm trying to do:
#include <iostream>
class String {
public:
char * p_start;
String(char * strSourc) // Constructor
{
p_start = strSourc;
}
};
int main()
{
String myString("Hello");
// Create object myString, send "Hello" string literal as argument
std::cout << myString.p_start << std::endl;
// Prints "Hello"
*myString.p_start = 'Y';
// Attempt to change value at first byte of myString.p_start
std::cout << myString.p_start << std::endl;
// Prints "Hello" (no change)
myString.p_start = "Yellow";
// Assigning a string literal to p_start pointer
std::cout << myString.p_start << std::endl;
// Prints Yellow, change works. I thought myString "Hello" was const chars, immutable
return 0;
}
So, I'm confused. I've looked everywhere and it says that string literals, like "Hello", are immutable, each of their char bytes are unchangeable. Though I managed to assign Yellow to the p_start pointer, changing the first letter. Though changing the single letter H to a Y through dereferencing the H pointer didn't do anything.
Any insights would help me, thanks.
I think you're confusing about pointer and pointee.
p_start = "Yellow", you're changing the value of pointer, to point to "Yellow". *p_start = 'Y', you're changing the value of pointee, the content p_start points to, not itself. As you said, "Yellow" are const chars, so the behaviour try to modify them is UB.
You can make a copy of it in the ctor, then you can modify the chars, which are managed by the class. Yes, it will be a new copy, but it won't be a waste of memory. And you have no choice if you want them to be changable.
not sure if anyone finds this helpful after so long but since I am learning myself I took your above code and made it work by copying. It now has a member variable for size and cleans up using delete when you assign a new string literal to it (const char*).
#include <iostream>
class String {
public:
char * p_start;
int m_size;
String(const char * strSourc) // Constructor
{
//The following will get the size of the parameter.
int SizeParameter=0;
while (*(strSourc+SizeParameter) != '\0')
{
SizeParameter++;
}
// size of string saved.
m_size = SizeParameter;
// allocate enough memory so we can copy strSourc
p_start = new char[SizeParameter+1];
//copy the contents strSourc
for(int i=0; i<SizeParameter+1; i++)
{
*(p_start+i) = *(strSourc+i);
}
}
//Handle change of string value.
char* AssignNewString (const char* newtext)
{
//clean
delete p_start;
int SizeParameter=0;
while (*(newtext+SizeParameter) != '\0')
{
SizeParameter++;
}
// size of string saved.
m_size = SizeParameter;
// allocate enough memory so we can copy strSourc
p_start = new char[SizeParameter+1];
//copy the contents strSourc
for(int i=0; i<SizeParameter+1; i++)
{
*(p_start+i) = *(newtext+i);
}
return p_start;
}
char* operator=(const char* newtext)
{
AssignNewString(newtext);
}
};
int main()
{
String myString("Hello");
// Create object myString, send "Hello" string literal as argument
std::cout << "string size: " << myString.m_size << std::endl;
std::cout << myString.p_start << std::endl;
// Prints "Hello"
*myString.p_start = 'Y';
// Attempt to change value at first byte of myString.p_start
std::cout << myString.p_start << std::endl;
// Prints "Hello" (no change)
myString = "yellow";
// Assigning a string literal to p_start pointer
myString = "THIS IS A LONGER STRING";
std::cout << myString.p_start << std::endl;
std::cout << "string size: " << myString.m_size << std::endl;
return 0;
}
Note I am learning myself so do let me know if I am doing something wrong. But so far, it seems to work.
Hi i have the following code:
char msg[10000];
string mystr = "hello";
I want to put mystr into msg. Is there a way to do that? I tried all sorts of methods, but keep getting:
incompatible types in assignment of 'const char*' to char [10000]'
I tried:
msg = mystr.c_str();
and
msg = (char[10000])mystr;
to no avail.
You can try std::copy for this. Something like:
std::copy(mystr.begin(), mystr.end(), msg);
I would avoid C string functions like mempcy and strcpy in C++.
Take a look at string::copy - it takes a string an puts it into an array.
In your case it would be:
std::size_t length = mystr.copy(msg,10000);
msg[length]='\0';
char msg[10000];
string mystr = "hello";
strcpy(msg, mystr.c_str());
cout<<msg;
Use copy member function of std::string:
size_t len = mystr.copy(msg, (sizeof msg)-1);
msg[len] = 0;
String assignment in C is different. You have to copy the bytes into your destination string.
memcpy_s(msg, 1000, mystr.c_str(), mystr.length()) // safe windows version
memcpy(msg, mystr.c_str(), mystr.length()) // unix version
Use strcpy function :
http://www.cplusplus.com/reference/clibrary/cstring/strncpy/
strncpy(msg, mystr.c_str(), sizeof msg / sizeof msg[0]);
msg[sizeof msg / sizeof msg[0] - 1] = 0; // null-terminate in case of truncation
Compilers sometimes produce wonky error messages for array types.
Here's an accumulation of previous answers into a paste-and-compile program.
#include <string>
#include <iostream>
#if 1
int main(int argc, char **argv)
{
using std::cout;
using std::endl;
char msg[1000] = {0}; // initialize to 0 here since we're printing below
// the <type> <array-name>[<size>] = {0} just fills a POD struct or an array with 0s
std::string mystr = "hello";
// if, at some point, you have things changing "mystr"
// you'll need to make sure that it will fit in msg[]
cout << "Before strcpy: \"" << msg << "\"" << endl;
// I'll just finish the statement in mystr...
mystr += " world!";
if(mystr.length() < sizeof(msg)){
strcpy(
msg, // <- put in here until we find a '\0'
mystr.c_str() // <- take from here (which could be a temporary buffer)
);
}
//MSC will complain about strcpy being unsafe
//
// you can use the below instead (if you really feel the need to), which is
// the MS-specific equivalent to the above.
/*
strcpy_s(
msg, // <- put in here until we find a '\0' or the size limit is reached
sizeof(msg), // <- don't put any more than this many chars in msg
mystr.c_str() // <- take from here
);
*/
cout << "After strcpy: \"" << msg << "\"" << endl;
return 0;
}
#else
// Similarly, using wchar_t (a usually non-byte-sized character type)
//
// note where the divisions occurr
int main(int argc, char **argv)
{
using std::wcout;
using std::endl;
wchar_t msg[1000] = {0};
std::wstring mystr = L"hello";
wcout << "Before strcpy: \"" << msg << "\"" << endl;
mystr += L" world";
if(mystr.length() < (sizeof(msg)/sizeof(wchar_t))){
// mystr wil fit!
wcscpy(
msg, // <- put in here until we find a '\0'
mystr.c_str() // <- take from here (which could be a temporary buffer)
);
}
// Similar to the char case in the first preprocessor block
/*
wcscpy_s(
msg, // <- put in here until we find a '\0' or the size limit is reached
sizeof(msg)/sizeof(wchar_t), // <- don't put any more than this many wchar_ts in msg
mystr.c_str() // <- take from here
);
*/
wcout << "After strcpy: \"" << msg << "\"" << endl;
return 0;
}
#endif
I shall leave it to you to read the documentation on all related functions.
I have the following program which is giving run time error:
*The instruction at "x" referenced memory at "y"
The memory could not be written.*
Code:
int main() {
char *str1 = "Rain";
char *&str2 = str1;
cout << str1 << str2 << endl;
*str1 = 'M';
cout << str1 << str2 << endl;
//Here the error happens
*str2 = 'P';
cout << str1 << str2 << endl;
return 0;
}
What is the cause of this error.
The problem is that a string literal is technically a 'char const pointer'. Reading right to left a pointer to unmodifiable characters. Because of backward comparability with 'C' this can be auto cast to 'char pointer' by the compiler. This does not mean that the underlying type has changed and thus modifying the underlying const object is undefined behavior.
char *str1 = "Rain"; // Lie this is not a char*
char const* str9 = "Rain"; // This is the real type.
// String lieterals => "XXXXX" are char const*
If you want to modify the string what you need to do is declare an array.
char str6[] = "Rain";
str6[0] = 'M';
*str6 = 'P';