how to convert const char [] to char * in c++ - c++

I compiled very simple code, but I couldn't compile this code.
#include <iostream>
using namespace std;
class String {
char *str;
public:
String(char *);
~String();
char *get() { return str; }
};
String::String(char *p)
{
cout << " ! constructor\n";
str = new char[strlen(p) + 1];
strcpy(str, p);
}
String::~String()
{
cout << " ! destructor\n";
delete str;
}
void show1(String &s)
{
cout << "show1 : " << s.get();
}
void show2(String s)
{
cout << "show2 : " << s.get();
}
int main()
{
char *str = "C++ Language";
String ss(str);
show1(ss); cout << endl;
show2(ss); cout << endl;
return 0;
}
error say it can't be converted const char [13] to char * .
how can I compile this code?
I compile this with visual studio.

String literals are constant and shouldn't be modified, older compilers might allow assigning them to char * but more modern compilers will only allow assignment to const char* (or const char[]), e.g. this should compile:
const char *str = "C++ Language";
Even if your compiler allows assignment to char * you should always use const char* to prevent hard to trace crashes when you try to modify a string literal.

As you only want to read the string, you want it to be const. Change
String::String(char *p)
...
char *str = "C++ Language";
to
String::String(const char *p)
...
const char *str = "C++ Language";

Include string.h for strlen and strcpy

Related

How to find the last character of an string and assign it to a char pointer?

I need Ptr to have first character of the string and BufLim to have last character of the string.
#include <iostream>
using namespace std;
int main()
{
const char* Str = "Stackoverflow";
const char* Ptr = Str[0];
const char* BufLim = &Ptr.back(); // pointer pointing to last character of *ptr
cout << Ptr;
cout << BufLim;
return 0;
}
Kindly help me on this.
Prior to c++17, use std::string instead of const char* string literals.
Then you can easily have the pointer to the first and the last char of the string by the help of member functions std::string::front and std::string::back respectively (given that the string is not empty).
#include <string>
using namespace std::string_literals;
std::string Str{ "Stackoverflow"s };
/* const */ char* ptrFirst = &Str.front();
/* const */ char* ptrLast = &Str.back();
std::cout << *ptrFirst << "\n"; // prints S
std::cout << *ptrLast; // prints w
(Alternatively) in c++17, you can use std::string_view, which is basically a wrapper around const char*. Like std::string, it has the same kind of member functions std::string_view::front and std::string_view::back
#include <string_view>
using namespace std::string_view_literals;
std::string_view Str{ "Stackoverflow"sv };
const char* ptrFirst = &Str.front();
const char* ptrLast = &Str.back();
std::cout << *ptrFirst << "\n"; // prints S
std::cout << *ptrLast; // prints w

difference between char and const char

# include <iostream>
# include <string.h>
using namespace std;
int main()
{
int a=10;
int b=20;
char op[10];
const char p='+';
cout<<"enter the operation"<<endl;
cin>>op;
if(!strcmp(op,p)==0)
{
cout<<a+b;
}
return 0;
}
compilation result
12 17 C:\Users\DELL\Documents\cac.cpp [Error] invalid conversion from 'char' to 'const char*' [-fpermissive]
I am a beginner. Please tell me what mistake have I done.
This isn't about the difference between char and const char, but between char [] and char.
strcmp expects two character arrays.
op is an array of (10) characters. Good: that's what strcmp expects.
p is a single character. Not good: strcmp needs a char array, and p isn't any kind of array, but a single character.
You can change p from a single char '+' to a char array "+", or compare only the 0th character of op, as suggested in a comment above.
there is no version of strcmp that takes a single character as a parameter but instead it takes two string and compares them.
if you want to compare a single char variable with a string you can compare it with the first element of string or with any other element:
#include <iostream>
#include <string>
int main()
{
char op[10] = "Hi";
const char p = '+';
// if( strcmp( op, p) ) // error cannot covert parameter 2 from char to const char*
// cout << "op and p are identic" << std::endl;
// else
// std::cout << "op and b are not identic" << std::endl;
if(op[0] == p)
std::cout << "op[0] and p are identic" << std::endl;
else
std::cout << "op[0] and p are not identic" << std::endl;
const char* const pStr = "Bye"; //constant pointer to constant character string: pStr cannot change neither the address nor the value in address
const char* const pStr2 = "bye"; // the same as above
// pStr++; //error
// pStr[0]++; // error
if( !strcmp( pStr, pStr2) )
std::cout << "pStr and pStr2 are identic" << std::endl;
else
std::cout << "pStr and pStr2 are Not identic" << std::endl;
return 0;
}

c++ replace what with with on char array(string)

I have the task to write a function char * stringReplace(const char * str, const char * what, const char * with) which replaces "what" with "with" on a new string with the correct length. So Inside the function I created dynamic array, which the function returns. But my question is how can I delete it after, as If i try to delete it in the main function, after i use it, it says it's undefined. Aren't dynamic arrays without a scope or I'm wrong?
Here's my code:
#include <iostream>
#include <string.h>
using namespace std;
bool areTheSame(const char * str, const char * what, unsigned p)
{
return areEqual;
}
unsigned howManyTimes(const char * str, const char * what)
{
}
char * stringReplace(const char * str, const char * what, const char * with)
{
}
int main()
{
char str[1000];
char what[1000];
char with[1000];
cout << "Enter your string\n";
cin.getline(str, 1000);
cout << "\nEnter \"what\" you want to replace\n";
cin.getline(what, 1000);
if (strlen(str) < strlen(what))
{
cout << "\"What\" contains more characters than the string!\n";
return 0;
}
cout << "\nEnter with what you want to replace it\n";
cin.getline(with, 1000);
cout << "\nYour string with replaced words looks like\n";
cout << stringReplace(str, what, with) << endl;
return 0;
}
P.S I deleted parts of the code as I found the answer I wanted and there is still time for the task, and I'm not sure I'm allowed to post my code publicly
You have to delete it in order to avoid memory leak. You can do something like this:
int main()
{
char str[1000];
char what[1000];
char with[1000];
char *replaced;
cout << "Enter your string\n";
cin.getline(str, 1000);
cout << "\nEnter \"what\" you want to replace\n";
cin.getline(what, 1000);
if (strlen(str) < strlen(what))
{
cout << "\"What\" contains more characters than the string!\n";
return 0;
}
cout << "\nEnter with what you want to replace it\n";
cin.getline(with, 1000);
cout << "\nYour string with replaced words looks like\n";
replaced = stringReplace(str, what, with);
cout << replaced << endl;
delete [] replaced;
return 0;
}
However note that this isn't the best pratice to split allocation/deallocation responsibility.

C++ copy constructor is not invoking (compilation error)

This code doesn't compile (please ignore passing by value in operator+, I could replace it by reference & but it still doesn't solve the issue)
I expect in main function:
String s3 = s + s2; // COMPILATION ERROR
to be compiled ok (because I declare copy constructor) but it gives error ("no matching constructor")
#include <iostream>
#include <string>
class String {
public:
String()
{
std::cout << "Constructor " << this << std::endl;
data = new char[100];
};
String(char * str) : String()
{
std::cout << "Char * Constructor " << this << std::endl;
strcpy(this->data,str);
};
String(String & rhs) : String() {
std::cout << "Copy Constructor " << this << std::endl;
strcpy(data, rhs.data);
};
void print() {
printf("%s\n",data);
}
~String() {
std::cout << "Destructor " << this << std::endl;
if (data) {
delete data;
data = nullptr;
}
};
friend String operator+(String s1, String s2);
private:
char * data;
};
String operator+(String s1, String s2)
{
String temp;
delete [] temp.data;
temp.data =
new char[strlen(s1.data) + strlen(s2.data) + 1];
strcpy(temp.data, s1.data);
strcat(temp.data, s2.data);
return temp;
}
int main(int argc, const char * argv[])
{
String s("herer");
s.print();
String s2 = s;
s2.print();
String s3 = s + s2; // COMPILATION ERROR
return 0;
}
There are several errors with your code. First
String(char * str)
Needs to be
String(const char * str)
If you want to use string literals like you do in main() with String s("herer");. Secondly Your copy constructor
String(String & rhs)
Needs to take be
String(const String & rhs)
So that it can bind to temporaries.
Third you need to include <cstring> or <string.h> in order to use strcpy().
Lastly you are using the wrong delete in you destructor. When you call new you use delete and when you use new[] you call delete []. You use new[] to allocate data but you are deleting it with delete.
You can see a working example of your code here
The argument of the copy constructor must be const&.
String(String const & rhs) : String() { ... }

Comparing std::string with constants vs comparing char arrays with constants In C++

I am trying to make a little text adventure to get a handle on C++.
cin >> keyboard1;
if ((keyboard1 == "inv")inventory(inv);
This will work if keyboard1 is a string, but won't if it's a char array, is this because I haven't included the null at the end of the constant?
Let'say your code is the following:
int main(int argc, char *argv[])
{
std::string s;
std::cin >> s;
std::cout << s << std::endl;
if (s == "inv") {
std::cout << "Got it" << std::endl;
}
return 0;
}
This works as expected because of the way the stl class string overrides the == operator.
You cannot expect the following code to work instead:
int main(int argc, char *argv[])
{
char *s = (char *)calloc(10, sizeof(char));
std::cin >> s;
std::cout << s << std::endl;
if (s == "inv") {
std::cout << "Got it" << std::endl;
}
return 0;
}
because you are comparing s, which is the address where the string starts to a constant string (which, by the way, is automatically null-terminated by the compiler).
You should use strcmp to compare "c-strings":
int main(int argc, char *argv[])
{
char *s = (char *)calloc(10, sizeof(char));
std::cin >> s;
std::cout << s << std::endl;
if (strcmp(s, "inv") == 0) {
std::cout << "Got it" << std::endl;
}
return 0;
}
This works.
No, the reason it won't work is because you will be comparing the address of the memory that represents each string. Use strcmp / wcscmp instead.
The reason why comparing a string and a constant work is because the string class will have an equality operator defined (e.g. bool StringClass:operator==(const char* pszString)).
If keyboard1 is a char array, then if (keyboard1 == "inv") is performing a simple pointer comparison (both become char*).
When keyboard1 is a string, it can call an operator==(cosnt string&, const char*) if one exists, otherwise, if the string has the non-explicit constructor string(const char *s), the constant "inv" would be implicitly converted to a string object, and operator==(const string&,const string&) applied.