So I want to do something like
printf("%s", '\t'*3);
Im just wondering if there is a way to print something like that without looping
printf("%s%s%s", "\t", "\t", "\t"); ? Just kidding. But since you have tagged this as C++, and since I don't know what higher-level problem you are trying to solve here, have you considered just using the appropriate std::string constructor?
std::string s(3, '\t');
You can even use it with printf if you really insist...
printf("%s", std::string(3, '\t').c_str());
But why not just use std::cout?
std::cout << std::string(3, '\t');
About the "without looping" part... both printf and std::string may have loops in their implementations, of course. But that should not bother you.
assuming that you ment runtime loops and are allowed to use boost, you could create the strings at compile time using templates:
#include <iostream>
#include <boost/mpl/char.hpp>
#include <boost/mpl/string.hpp>
using namespace boost;
template <unsigned int C, int R>
struct repchrn
{
typedef typename mpl::push_back<typename repchrn<C, R - 1>::string, mpl::char_<C>>::type string;
static const char* getString() { return mpl::c_str<string>::value; }
};
template <unsigned int C>
struct repchrn<C, 0>
{
typedef mpl::string<> string;
static const char* getString() { return mpl::c_str<string>::value; }
};
int main() {
printf("%s", repchrn<'a', 5>::getString());
/* or */ std::cout << std::endl;
std::cout << repchrn<'a', 5>::getString();
}
Related
Is there any way to print a string as quoted using {fmt}?
Here is an example code showing what I want to achieve:
fmt::print("Hello {}!", "Terens");
I want the code to print Hello "Terens"! instead of just Hello Terens!.
EDIT: I want to use the API for printing different data not known beforehand (I am writing this for a library, so I specifically want a quoted output when the data is a std::string or std::string_view.
You can either wrap "{}" in quotes in the format string or use std::quoted. For example (https://godbolt.org/z/f6TTb5):
#include <fmt/ostream.h>
#include <iomanip>
int main(){
fmt::print("Hello {}!", std::quoted("Terens"));
}
Output:
Hello "Terens"!
I want to use the API for printing different data not known beforehand (I am writing this for a library, so I specifically want a quoted output when the data is a std::string or std::string_view.
The following code:
#include <fmt/core.h>
template<typename T>
const T& myprint_get(const T& t) {
return t;
}
std::string myprint_get(const std::string& t) {
return "\"" + t + "\"";
}
template<typename ...T>
void myprint(const char *fmt, T... t) {
fmt::print(fmt, myprint_get(t)...);
}
int main() {
myprint("{} {}", std::string("string"), 5);
}
outputs:
"string" 5
It should be enough to get you started.
Is there any solution to run a function/macro that name is created by concatenation of two strings?
I just want to do something like that:
template <char *A, char *B, int C>
int function_that_run_other_function(void){
// Here is the main point
char function_name[80];
strcpy (function_name, "function");
strcat (function_name, A);
strcat (function_name, B);
return function_name(C);
}
I can do this using macro:
#define macro_that_run_function(A,B,C) \
function_##A##B##(C);
But I don't want to use macro because of many problems with macros.
Is it possible to do in C++ without any additional libraries?
I got curious and after a little while I ended up with this ungodly mess and general mainentace nightmare:
main.cpp:
#include <map>
#include <iostream>
#include <sstream>
#include <functional>
#include <cstring>
typedef std::function<void(int)> func;
typedef std::map<std::string, func> FuncMap;
template <char* A, char* B, int C>
void runner(FuncMap funcs){
std::stringstream ss;
ss <<A <<B;
return funcs[ss.str()](C);
}
void ABC(int val) {
std::cout <<"Woo: " <<val <<"\n";
}
extern char a[]; //due to external linkage requirement
extern char b[];
int main(...) {
FuncMap funcs;
strcpy(a, "A");
strcpy(b, "B");
funcs["AB"] = std::bind(&ABC, std::placeholders::_1);
runner<a, b, 0>(funcs);
return 0;
}
vars.cpp:
char a[5] = {""};
char b[5] = {""};
So yes with enough force you can make c++ do something along the lines of what you want, but I really wouldn't recommend it.
No, C++ does not allow the compile or run time manipulation or inspection of symbol names (barring the implementation specified type info stuff).
Dynamic libraries often export names (mangled for C++, almost unmangled for `extern "C"``), and libraries for loading them usually (always?) allow them to be loaded by string value.
I have a following problem: I am reusing old code that uses real_p parser to parse real numbers. I would like to capture each number, convert it to string, and put it in vector of strings.
I am using the following code, where l_double is a variable of the type double, convertdouble function converts a double to a string, and result.m_literalValues is the vector of strings.
However, the code will not assign a parsed value to l_double.
rule<> alternative3 = +(real_p [assign_a(l_double)]
[push_back_a(result.m_LiteralValues, convertdouble(l_double))]
>> str_p(",")
)
Does anyone has an idea what am I doing wrong ?
Note: I will not re-engineer the old code, which is much more complex than the example given. I just want to extract the strings of all values parsed, and to put them in the vector of strings.
The problem seems to be located in push_back_a(result.m_LiteralValues, convertdouble(l_double)), specifically in convertdouble(l_double). push_back_a requires that its second argument be a reference to be stored in a "policy holder actor" so using the function call there causes the error. If you don't need to store l_double and were simply using it as a temporary, one way to accomplish what you want is creating your own phoenix function that behaves similarly to push_back_a as explained here(full example here).
You define the phoenix function like this:
struct push_back_impl
{
template <typename Container, typename Item>
struct result
{
typedef void type;
};
template <typename Container, typename Item>
void operator()(Container& c, Item const& item) const
{
c.push_back(convertdouble(item));
}
};
function<push_back_impl> const push_back = push_back_impl();
and then define your rule like this:
rule<> alternative3 = +( real_p[push_back(var(result.m_LiteralValues),arg1)] >> str_p(",") );
Full compilable code(change the for loop to show the results if you can't/don't want to use c++11):
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_operators.hpp>
#include <boost/spirit/include/phoenix1_functions.hpp>
#include <boost/spirit/include/phoenix1_primitives.hpp>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace boost::spirit::classic;
using namespace phoenix;
std::string convertdouble(const double& d)
{
std::stringstream ss;
ss<<d;
return ss.str();
}
struct push_back_impl
{
template <typename Container, typename Item>
struct result
{
typedef void type;
};
template <typename Container, typename Item>
void operator()(Container& c, Item const& item) const
{
c.push_back(convertdouble(item));
}
};
function<push_back_impl> const push_back = push_back_impl();
struct Results
{
std::vector<std::string> m_LiteralValues;
};
int main()
{
Results result;
char const* test="2.5,3.6,4.8,";
rule<> alternative3 = +( real_p[push_back(var(result.m_LiteralValues),arg1)] >> str_p(",") );
if(parse(test,alternative3,space_p).full)
{
std::cout << "success" << std::endl;
for(auto& str :result.m_LiteralValues)
std::cout << str << std::endl;
}
else
{
std::cout << "failure" << std::endl;
}
return 0;
}
This question already has answers here:
Is it possible to print a variable's type in standard C++?
(25 answers)
Closed 5 years ago.
While playing with templates in c++ I encountered a problem converting typename T to string. For example:
template <typename T>
class Matrix {
public:
Matrix() {
//my_type = string type of T. i.e. if T is char. I want my_type to be "char".
}
string my_type;
}
How do I convert T to a string that says what T is.
Note: I'm just playing around so please do not worry about when one might need such a thing.
There is no built-in mechanism for this.
typeid(T)::name() can give some info, but the standard does not mandate this string to be human-readable; just that it has to be distinct for each type. (E.x. Microsoft Visual C++ uses human-readable strings; GCC does not.)
You can build your own system though. For example, traits-based. Something like this:
// default implementation
template <typename T>
struct TypeName
{
static const char* Get()
{
return typeid(T).name();
}
};
// a specialization for each type of those you want to support
// and don't like the string returned by typeid
template <>
struct TypeName<int>
{
static const char* Get()
{
return "int";
}
};
// usage:
const char* name = TypeName<MyType>::Get();
For GCC you have to use a trick. Using cxxabi.h, I wrote a little wrapper for this purpose:
#include <string>
#include <iostream>
#include <iomanip>
#include <typeinfo>
#include <cxxabi.h>
#define DEBUG_TYPE(x) do { typedef void(*T)x; debug_type<T>(T(), #x); } while(0)
template<typename T>
struct debug_type
{
template<typename U>
debug_type(void(*)(U), const std::string& p_str)
{
std::string str(p_str.begin() + 1, p_str.end() - 1);
std::cout << str << " => ";
char * name = 0;
int status;
name = abi::__cxa_demangle(typeid(U).name(), 0, 0, &status);
if (name != 0) { std::cout << name << std::endl; }
else { std::cout << typeid(U).name() << std::endl; }
free(name);
}
};
The double parentheses are necessary. Will work with any type.
Now you can use it for boost::mpl:
DEBUG_TYPE((if_c<true, true_, false_>::type));
will print:
if_c<true, true_, false_>::type => bool_<true>
You can't, at least not directly. The only way to convert a token or series of tokens into a string literal is using the preprocessor's stringization operator (#) inside of a macro.
If you want to get a string literal representing the type, you'll have to write something yourself, perhaps by using a macro to instantiate the template and pass it the stringized type name.
One problem with any general approach is: what string should be given for the following uses:
Matrix<char> x;
typedef char MyChar;
Matrix<MyChar> y;
Both x and y are of the same type, but one uses char directly and the other uses the typedef MyChar.
It is impossilbe to get name of type in string if the type is one of base types. For user defined types you can use typeid(my_type).name(). Also you need #include <typeinfo> :)
more info...
workaround way...
#define Tprint(x) print<x>(#x)
template<typename T>
void print (string ltype){
cout<<ltype<<" = "<<sizeof(T)<<endl;
}
You could use a C++ reflection library. So:
using namespace ponder;
Class::declare<Matrix>();
std::string const& name = classByType<Matrix>().name();
This gives you other options as well once you have the metaclass information, like looking what the class members are.
template< typename From,typename To>
static inline bool superConvert(const From& fromVar,To& toVar)
{
stringstream ss;
ss<<fromVar;
ss>>toVar;
if(ss.fail())
{
return false;
}
else
{
From tempFrom;
stringstream ss;
ss<<toVar;
ss>>tempFrom;
if(tempFrom != fromVar)
{
return false;
}
else
{
return true;
}
}
}
Is there any function in C++ which converts all data types (double, int, short, etc) to string?
Usually you'll use the << operator, in conjunction with (for example) a std::stringstream.
http://www.boost.org/doc/libs/1_43_0/libs/conversion/lexical_cast.htm
If boost is not an option (it should always be, but just in case):
#include <sstream>
#include <string>
template<class T1, class T2>
T1 lexical_cast(const T2& value)
{
std::stringstream stream;
T1 retval;
stream << value;
stream >> retval;
return retval;
}
template<class T>
std::string to_str(const T& value)
{
return lexical_cast<std::string>(value);
}
Boost has a similar idea, but the implementation is much more efficient.
There is no built-in universal function, but boost::lexical_cast<> will do this.
Why do you need this conversion? A lot of languages have variant types which auto-convert, and this can lead to wanting that behavior in C++ even though there may be a more canonical way of implementing it.
For example if you're trying to do output, using a (string)stream of some sort is probably the way to go. If you really need to generate and manipulate a string, you can use boost::lexical_cast http://www.boost.org/doc/libs/1_43_0/libs/conversion/lexical_cast.htm.
Here is the one I use from my utility library. This was condensed from other posts here on stackoverflow, I am not claiming this as my own original code.
#include <string>
#include <sstream>
using namespace std;
template <class T>
string ToString(const T& Value) {
stringstream ss;
ss << Value;
string s = ss.str();
return s;
}
also, another handy string formatting utility I use:
#include <string>
#include <stdarg.h> /* we need va_list */
// Usage: string myString = FormatString("%s %d", "My Number =", num);
string FormatString(const char *fmt, ...) {
string retStr;
if (NULL != fmt) {
va_list marker = NULL;
va_start(marker, fmt);
size_t len = 256 + 1; // hard size set to 256
vector <char> buffer(len, '\0');
if (vsnprintf(&buffer[0], buffer.size(), fmt, marker) > 0) {
retStr = &buffer[0]; // Copy vector contents to the string
}
va_end(marker);
}
return retStr;
}
For this use stringstream.
First include the header file as #include .
Then create an object of stringstream and using stream insertion operator (<<) pass the contents you want to convert as string.
Ex:
#include <iostream>
#include <sstream>
int main(){
std::string name = "Ram";
float salary = 400.56;
std::stringstream obj;
obj << name << " salary: " << salary;
std::string s = obj.str();
std::cout << s;
}