how to pass a parameter to char*? - c++

As in the code below, I can't pass this parameter, how do I fix it?
E0167 The "const char *" type argument is incompatible with the "char *" type parameter
Code example:
#include <iostream>
using namespace std;
int PrintString(char* s)
{
cout << s << endl;
}
int main(int argc, char* argv[])
{
PrintString("TESTEEEE");
return 0;
}
I've already tried PrintString(L"TESTEEEE");
I've also tried setting the Project -> Properties -> General -> Character Set option to use Multi-Byte Character Set.

This literal "TESTEEEE" is of type char const[9]. When used as an argument to a function, it can decay to char const* but not to char*. Hence to use your function, you have to make the parameter fit to your argument or the opposite as follows
#include <iostream>
using namespace std;
int PrintString(const char* s)
{
cout << s << endl;
}
int main(int argc, char* argv[])
{
PrintString("TESTEEEE");
return 0;
}
live
OR
#include <iostream>
using namespace std;
int PrintString( char* s)
{
cout << s << endl;
}
int main(int argc, char* argv[])
{
char myArr[] = "TESTEEEE";
PrintString(myArr);
return 0;
}
live

You have incorrect constness, it should be:
void PrintString(const char* s)

Related

C++ char* as a function parameter

How can I pass a char pointer (char*) to the function func()?
#include <iostream>
using namespace std;
void func(char *var)
{
cout << var;
}
int main()
{
char* test = "Hello World";
func(test);
}
The compiler says:
Initialization: const char[12] cannot be converted to char *
A string literal is a const char[N] array in read-only memory (where N is the number of characters in the literal, plus 1 for the null terminator, so in your case 11+1=12). You can't point a char* pointer (ie, a pointer to non-const data) at a string literal, as that would allow for the possibility of altering read-only data, which is undefined behavior.
Simply change your pointer type to const char* instead (ie a pointer to const data), eg.
#include <iostream>
using namespace std;
void func(const char *var)
{
cout << var;
}
int main()
{
const char* test = "Hello World";
func(test);
}
Otherwise, as you say you have no control over the function declaration, then if you really want to pass a string literal to a char* pointer, you should copy the characters into a separate writable char[] buffer first, and then point at that instead, eg:
#include <iostream>
using namespace std;
void func(char *var)
{
cout << var;
}
int main()
{
char test[] = "Hello World";
func(test);
}
Or, if you know for sure that the function will never modify the characters, you can just cast off the const-ness using const_cast (though this is highly NOT recommended, I'm including it for completeness), eg:
#include <iostream>
using namespace std;
void func(char *var)
{
cout << var;
}
int main()
{
char* test = const_cast<char*>("Hello World");
func(test);
/* alternatively:
const char* test = "Hello World";
func(const_cast<char*>(test));
*/
}
This code would print the string "Hello World"
void func(char *var)
{
for( ;*var!='\0'; var++) { //!= from null terminator
cout<<*var;
}
}
int main()
{
char test[] = "Hello World";
func(test);
return 0;
}

Isn't qualifier upcast/upgrade automatic? [duplicate]

Why my compiler(GCC) doesnt implicitly cast from char** to const char**?
Thie following code:
#include <iostream>
void print(const char** thing) {
std::cout << thing[0] << std::endl;
}
int main(int argc, char** argv) {
print(argv);
}
Gives the following error:
oi.cpp: In function ‘int main(int, char**)’:
oi.cpp:8:12: error: invalid conversion from ‘char**’ to ‘const char**’ [-fpermissive]
oi.cpp:3:6: error: initializing argument 1 of ‘void print(const char**)’ [-fpermissive]
Such a conversion would allow you to put a const char* into your array of char*, which would be unsafe. In print you could do:
thing[0] = "abc";
Now argv[0] would point to a string literal that cannot be modified, while main expects it to be non-const (char*). So for type safety this conversion is not allowed.
#Fred Overflow's link to the FAQ is a complete answer. But (sorry Marshall) it's not the most clear explanation. I don't know if mine is more clear, but I hope so.
The thing is, if p is a char* pointer, then it can be used to modify whatever it's pointing at.
And if you could obtain a pointer pp that points to p, but with pp of type char const**, then you could use pp to assign to p the address of a const char.
And with that, you could then use p to modify the const char. Or, you would think you could. But that const char could even be in read-only memory…
In code:
char const c = 'a';
char* p = 0;
char const** pp = &p; // Not allowed. :-)
*pp = &c; // p now points to c.
*p = 'b'; // Uh oh.
As a practical solution to your code that does not compile, …
#include <iostream>
void print(const char** thing) {
std::cout << thing[0] << std::endl;
}
int main(int argc, char** argv) {
print(argv); // Dang, doesn't compile!
}
just do …
#include <iostream>
void print( char const* const* thing )
{
std::cout << thing[0] << std::endl;
}
int main( int argc, char** argv )
{
print( argv ); // OK. :-)
}
Cheers & hth.,
Note, that although
void dosmth(const char** thing);
int main(int argc, char** argv) {
dosmth(argv);
is forbidden, you can and should do
void dosmth(const char* const* thing);
int main(int argc, char** argv) {
dosmth(argv);
Which is probably what you wanted anyway. The point here is that thing now refers to a const char* array which is itself immutable and which referenced values char are themselves immutable.
So, for a "look at it, but do not change it" scenario, const char* const* is the type to use.
Note: I used the more common (but in my opinion inferior) standard of trying to write the const modifier as left as possible. Personally, I recommend writing char const* const* instead of const char* const* as it is hugely more concise that way.
Because it might allow us to modify a constant value. Read here to understand why: http://c-faq.com/ansi/constmismatch.html

C String assigning values in explicit constructor in C++?

I have a class BankAccount with two string members - name and num. What I want is to assign values to these objects when I create them (when the constructor is called). However the compiler says No instance of constructor matches the argument list when I try to create an object.
I would like to ask why is that?
// hwk-2.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include "pch.h"
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
class BankAccout {
char name[23];
char num[15];
double sum;
public:
BankAccout(char *nm, char *nr, double s) {
strcpy(name,nm);
strcpy(num, nr);
sum = s;
}
};
int main()
{
BankAccout k("Peter", "0403940940", 34.21);
}
as a coffee break exercise here is more idiomatic version
#include "pch.h"
#include <iostream>
#include <string>
class BankAccount {
std::string name_;
std::string num_;
double sum_;
public:
BankAccount(std::string name, std::string num, double sum) {
name_ = name;
num_ = num;
sum_ = sum;
}
};
int main()
{
BankAccount k("Peter", "0403940940", 34.21);
}
The signature of the constructor does not match.
This one will match:
BankAccount(const char *nm, const char *nr, double s);
EDIT:
The reason is the way you are calling the constructor in the main function. You are giving literal strings as parameters. These literals are const, you cannot change them at runtime. Thus you will pass pointers to const char*.
This is very obvious if you look at this opposing example. This is a way that would be compatible with the old signature BankAccout(char *nm, char *nr, double s);.
int main(int argc, char* argv[])
{
char name[] = "hello";
char number[] = "1234";
std::cout << "name before: " << name << std::endl;
BankAccount k(name, number, 8.5);
// name and number are not const,
// you can change them :
name[2] = 'x';
name[3] = 'x';
std::cout << "name after: " << name << std::endl;
return 0;
}
An even simpler version, if you don’t need to have additional functionality in the class: just use a struct.
#include <string>
struct BankAccount {
std::string name;
std::string number;
double balance;
};
int main() {
BankAccount account{"Joy", "44", 43.};
}

usage on c++ function pointer

I'm a newbie to C++, learning pointer of function recently, a little confused by usage of pointer of function;
I practiced the following code:
#include <iostream>
#include <sstream>
using namespace std;
int subtraction(int a,int b){
return a-b;
}
int main(int argc, const char * argv[])
{
int (*minus)(int,int)=subtraction;
cout<<minus(5,4);
return 0;
}
it works well;
so,I try a little variation:
#include <iostream>
#include <sstream>
using namespace std;
int subtraction(int a,int b){
return a-b;
}
int main(int argc, const char * argv[])
{
int *minus(int,int)=subtraction;//only here different!
cout<<minus(5,4);
return 0;
}
I practiced it in Xcode on Mac,it give me Error:
Illegal initializer (only variables can be initialized)
but I think compiler can recognized the two is same,why must have a pair of parenthesizes?
In your original code
int (*minus)(int,int)=subtraction;
declares minus as a function pointer that takes parameter int, int and returns int.
In your second code
int *minus(int,int)=subtraction;
declares minus as a function that takes parameter int, int and returns a pointer int *.
You can use a function name(which is automatically converted to a function pointer) to initialize a function pointer, but you can't initialize a function.
This is a matter of operator precedence. The function call operator () has a higher precedence than the dereference operator *. So you must use parentheses to specify the correct order of evaluation.
int *minus(int, int)
means: First call a function named minus, then dereference the return value (int* in this case).
int (*minus)(int, int)
means: First dereference "minus", which returns a function, and then call that function.
You have tagged your code C++ and using iostream so I can safely assume you are looking for a C++ solution.
In such scenario, its best to use class template std::function instead of the function pointer syntax that is prone to error.
#include <iostream>
#include <sstream>
#include <functional>
int subtraction(int a,int b){
return a-b;
}
int main(int argc, const char * argv[])
{
std::function<int(int,int)> minus = subtraction;
//int (*minus)(int,int)=subtraction;
std::cout<<minus(5,4);
return 0;
}
Alternatively, if you would still want to continue with pointer to function, typedefs are recommended
#include <iostream>
int subtraction(int a,int b){
return a-b;
}
typedef int (*MINUS)(int,int);
int main(int argc, const char * argv[])
{
MINUS minus = subtraction;
//int (*minus)(int,int)=subtraction;
std::cout<<minus(5,4);
return 0;
}
And finally, another widely used option is to use functors.
#include <iostream>
struct MINUS
{
int operator()(int a,int b){
return a-b;
}
};
int main(int argc, const char * argv[])
{
//int (*minus)(int,int)=subtraction;
MINUS minus;
std::cout<<minus(5,4);
return 0;
}

How to use qsort for string in C++

I want to use qsort function to sort the characters in the strings using C++.
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
int compare_str(void const *a,void const *b){
char const *aa=(char const *)a;
char const *bb=(char const *)b;
if(*aa==*bb) return 0;
else if(*aa>*bb) return 1;
else return -1;
}
int main(){
string str="cake";
int len=str.length();
qsort(str,len,sizeof(str[0]),compare_str);
cout<<str;
return 0;
}
But it throws :
20 42 [Error] cannot convert 'std::string {aka std::basic_string<char>}' to 'void*' for argument '1' to 'void qsort(void*, size_t, size_t, int (*)(const void*, const void*))'
It would be great if anyone could provide an efficient way to do this.
I strongly recommend the modern method of
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string s("cake");
std::sort(s.begin(), s.end());
std::cout << s << std::endl; // Prints "acek".
return 0;
}
Plus, using std::sort over qsort allows the compiler to optimize better, so it's a win-win...
Your comparator for qsort expects C strings, not C++ std::strings. You should either declare str to be char str[]
char str[] = "cake";
qsort(str, strlen(cake), sizeof(char), compare_str); // Consider renaming to compare_char
or (better) use std::sort:
string str = "cake";
sort(str.begin(), str.end());
If you really want to do this, just pass a pointer to the string's contents:
qsort(str.c_str(),len,sizeof(str[0]),compare_str);
That said, you really should consider using the functions provided in the STL rather than those from the old C library...
You should use the function sort() under the header <algorithm>. This function is very flexible and you can use it in different manner. For sorting as you wish in question you can just write:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s="cake";
sort(s.begin(), s.end());
cout << s << endl;
return 0;
}
//output: acek
again by using sort() we can implement it in a range. If you want to sort first two element , the code will be
sort(s.begin(), s.begin()+2);
for above code the output will be
//output: acke
so if we want to sort first n element then we can write
sort(s.begin,s.begin()+n);
we can also modify the sort function. In that case we have to pass three parameter instead of two. The third parameter will be a functions which returns a bool value.For example , if we want to sort in descending order then our code will be like this
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
bool desc(char i, char j)
{
return i>j;
}
int main()
{
string s="cake";
sort(s.begin(), s.end(),desc);
cout << s << endl;
return 0;
}
//output: keca
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
int compare_str(void const *a,void const *b){
char const *aa=(char const *)a;
char const *bb=(char const *)b;
if(*aa==*bb) return 0;
else if(*aa>*bb) return 1;
else return -1;
}
int main(){
string str="cake";
int len=str.length();
qsort(const_cast<char*>(str.c_str()),len,sizeof(str[0]),compare_str);
cout<<str<<endl;
return 0;
}