How to pass a string as default argument in C++ - c++

How can I properly pass a const string, for example: "Hello" as a default parameter to a constructor without getting any warnings and errors? In other words how can I preserve memory for them before the function is called?

#include <iostream>
const char *defString = "Hello";
void foo(const char *str = defString) {
std::cout << str;
}
int main() {
foo();
foo("Hello, world!\n");
}

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;
}

Assigning const std::string to std::string in c++

I am trying to assign a const std::string variable to std::string variable.But getting some memory related error. code is like below:
#include <iostream>
#include <string>
using namespace std;
std::string sender1;
std::string fun()
{
const std::string sender = "hi";
sender1.assign(sender);
}
int main()
{
fun();
cout<<sender1<<endl;
return 0;
}
You've forgotten a return in fun. If you change that function like this:
std::string fun()
{
const std::string sender = "hi";
sender1.assign(sender);
return sender;
}
then the code will compile and run fine.
I got the answer finally.
We need to declare a char * globally. Then using const_cast <char *> we can convert the constant string to char and assign it.
Example: in .h file:
char * abc;
in .cc file:
func()
{
const std::string cde = "Hello";
//now to use this constant string in another function,we use const cast and
//assign it to abc like below
abc = const_cast <char *>(cde.c_str());
}

Variadic Macro: cannot pass objects of non-trivially-copyable type through '...'

I am trying to write a macro for logging mechanism. I wrote a variadic macro but it does not work with std::string. The code looks like the following:
#include <stdio.h>
#include <string>
#define LOG_NOTE(m, ...) printf(m, ##__VA_ARGS__)
int main()
{
std::string foo = "random string";
int bar = 5;
LOG_NOTE("%s %d %s", "Hello World", bar, foo);
return 0;
}
If I would call the macro like following, I would not get any error.
LOG_NOTE("%s %d %s", "Hello World", bar, "random string");
Compiler Output:
In function 'int main()': 5:49: error: cannot pass objects of
non-trivially-copyable type 'std::string {aka class
std::basic_string}' through '...' 11:5: note: in expansion of
macro 'LOG_NOTE'
The issue here is not the variadic macro, but the call to printf. Have a look at the documentation: the format specifier "%s" corresponds to char*, not std::string. printf can only handle primitive builtin types. You can change you invocation to
LOG_NOTE("%s %d %s", "Hello World", bar, foo.c_str());
to fix this.
I wrote a variadic macro
Don't. Use a variadic template function.
The actual problem you have is that you're trying to pass a C++ object (std::string) through a C API (printf). This is not possible.
You'd need some mechanism for conversion, for example:
#include <stdio.h>
#include <string>
template<class T>
decltype(auto) convert_for_log_note(T const& x)
{
return x;
}
decltype(auto) convert_for_log_note(std::string const& x)
{
return x.c_str();
}
template<class...Args>
void LOG_NOTE(const char* format, Args&&...args)
{
printf(format, convert_for_log_note(args)...);
}
int main()
{
std::string foo = "random string";
int bar = 5;
LOG_NOTE("%s %d %s\n", "Hello World", bar, foo);
return 0;
}
Example output:
Hello World 5 random string
http://coliru.stacked-crooked.com/a/beb3431114833860
Update:
For C++11 you'll need to spell out the return types by hand:
#include <stdio.h>
#include <string>
template<class T>
T const& convert_for_log_note(T const& x)
{
return x;
}
const char* convert_for_log_note(std::string const& x)
{
return x.c_str();
}
template<class...Args>
void LOG_NOTE(const char* format, Args&&...args)
{
printf(format, convert_for_log_note(args)...);
}
int main()
{
std::string foo = "random string";
int bar = 5;
LOG_NOTE("%s %d %s\n", "Hello World", bar, foo);
return 0;
}
You cannot pass object to printf, so you have currently to use
LOG_NOTE("%s %d %s", "Hello World", bar, foo.c_str());
If you don't need formatting, and just write every argument separated with space, you might simply use variadic template instead of MACRO:
template <typename ... Ts>
void LOG_NOTE(const Ts&...args)
{
const char* sep = "";
(((std::cout << sep << args), sep = " "), ...); // C++17 folding expression
// C++11/C++14 version are more verbose:
// int dummy[] = {0, ((std::cout << sep << args), (sep = " "), 0)...};
// static_cast<void>(dummy); // avoid warning for unused variable
}
int main()
{
std::string foo = "random string";
int bar = 5;
LOG_NOTE("Hello World", bar, foo);
}
Demo
I could not get #richardhodges nice solution to work in any of the C++11 compilers I tried. However, the following works with gcc -std=c++11:
#include <stdio.h>
#include <string>
template<class T>
T convert_for_log_note(T const& x)
{
return x;
}
inline const char* convert_for_log_note(std::string const& x)
{
return x.c_str();
}
template<class...Args>
void LOG_NOTE(const char* format, Args&&...args)
{
printf(format, convert_for_log_note(args)...);
}
int main()
{
std::string foo = "random string";
int bar = 5;
LOG_NOTE("%s %d %s\n", "Hello World", bar, foo);
return 0;
}
The inline keyword is necessary with the above solution for the Arduino C++ compiler, whereas other g++ compilers do not require it (the ones I have tried, anyways). Without this keyword, the Arduino code compiles, but the linker complains about multiple definitions.

Returning a C string stored in a class

I am trying to print out a C string that is stored in a class by returning the value using an accessor function.
Thanks for any help!
This is the error I get when I compile:
cstringClass.cpp: In member function 'char Foo::get_name()':
cstringClass.cpp:37:9: error: invalid conversion from 'char*' to 'char' [-fpermi
ssive]
return name;
^
Here is the code:
#include <iostream>
#include <cstring>
using namespace std;
class Foo
{
public:
void set_name(char a[]);
char get_name();
private:
char name[10];
};
int main()
{
Foo bar;
char a[10] = "Test";
bar.set_name(a);
cout << bar.get_name();
return 0;
}
void Foo::set_name(char a[])
{
strcpy(name, a);
}
char Foo::get_name()
{
return name;
}
So the error says:
cstringClass.cpp: In member function 'char Foo::get_name()':
^^^^^^^^^^^^^^^^^^^^
And indeed:
char get_name();
You declared get_name as returning a single char, not a pointer to a string. You probably meant char *get_name();.
As the error message states, your get_name() function doesn't return the appropriate type, which should be char* based on the data it returns, which is name[10]. char returns only 1 byte of data and name[10] has 10. Please see the corrected code below.
#include <iostream>
#include <cstring>
using namespace std;
class Foo
{
public:
void set_name(char a[]);
char *get_name(); //<-- correction
private:
char name[10];
};
int main()
{
Foo bar;
char a[10] = "Test";
bar.set_name(a);
cout << bar.get_name();
return 0;
}
void Foo::set_name(char a[])
{
strcpy(name, a);
}
char *Foo::get_name() //<-- correction
{
return name;
}

why runtime error occurs in this code sample related about return const reference?

std::string const& foo()
{
return "Hello World";
}
/*
int main()
{
std::string str = foo(); // runtime error
}
*/
int main()
{
foo(); // ok
}
why 'runtime error' occurs in this code sample but in other can work about return const reference?
the first main is error, but the second is ok.
Your function foo has undefined behavior. It is returning a reference to a locally created object, which is destroyed when the function returns. Your second main is not okay. It happens to not exhibit any obvious visible errors in your case, but it is still wrong.
#include <windows.h>
#include <string>
using namespace std;
std::string const foo() {
std::string str = "Hello World";
return str;
}
int main() {
foo(); // ok
std::string str = foo(); // ok
}