how to convert single-byte string to wide string in c++? - c++

I know the encoding and that the input string is 100% single byte, no fancy encodings like utf etc. And all I want is to convert it to wchar_t* or wstring basing on a known encoding. What functions to use ? btowc() and then loop ? Maybe string objects have something useful in them. There are lot of examples but all are for "multibyte" or fancy loops with btowc() that only show how to display output on screen that indeed this function is working, I haven't seen any serious example how to deal with buffers in such situation, is always wide char 2x larger than single char string ?

Try this template. It served me very well.
(author unknown)
/* string2wstring.h */
#pragma once
#include <string>
#include <vector>
#include <locale>
#include <functional>
#include <iostream>
// Put this class in your personal toolbox...
template<class E,
class T = std::char_traits<E>,
class A = std::allocator<E> >
class Widen : public std::unary_function<
const std::string&, std::basic_string<E, T, A> >
{
std::locale loc_;
const std::ctype<E>* pCType_;
// No copy-constructor, no assignment operator...
Widen(const Widen&);
Widen& operator= (const Widen&);
public:
// Constructor...
Widen(const std::locale& loc = std::locale()) : loc_(loc)
{
#if defined(_MSC_VER) && (_MSC_VER < 1300) // VC++ 6.0...
using namespace std;
pCType_ = &_USE(loc, ctype<E> );
#else
pCType_ = &std::use_facet<std::ctype<E> >(loc);
#endif
}
// Conversion...
std::basic_string<E, T, A> operator() (const std::string& str) const
{
typename std::basic_string<E, T, A>::size_type srcLen =
str.length();
const char* pSrcBeg = str.c_str();
std::vector<E> tmp(srcLen);
pCType_->widen(pSrcBeg, pSrcBeg + srcLen, &tmp[0]);
return std::basic_string<E, T, A>(&tmp[0], srcLen);
}
};
// How to use it...
int main()
{
Widen<wchar_t> to_wstring;
std::string s = "my test string";
std::wstring w = to_wstring(s);
std::wcout << w << L"\n";
}

Related

Autocasting C++ char array as string

Let's say I have a String class that can be constructed with a char array pointer. Is there any crazy way, through some magical operator overload, free function, or preprocessor macro to make Python-like syntax work, autocasting a char array literal to a String? To make this compile:
String a = "Foo".substr(1);
I suppose a wild pre-compile sed statement would do it, but something within the abilities of clang would be preferred.
For C++11 and beyond
#include <iostream>
#include <string>
int main() {
using namespace std::string_literals;
auto a = "foo"s.substr(1);
}
If you wanted to write this for your own String class then the way to get the same behavior would be to roll your own user defined string literal, and then do the same
#include <cstddef>
class Str {
public:
explicit Str(const char*) {}
Str substr(int) { return *this; }
};
Str operator"" _s (const char* input, std::size_t) {
return Str{input};
}
int main() {
auto s = "something"_s.substr(1);
}

Swapping a stringstream for cout

With glibc's stdio, I can swap a memstream for stdout, thereby capturing the output of a piece of code compiled to output to stdout:
#include <stdio.h>
void swapfiles(FILE* f0, FILE* f1){ FILE tmp; tmp = *f0; *f0 = *f1; *f1 = tmp; }
void hw_c(){ puts("hello c world"); }
int c_capt(){
FILE* my_memstream;
char* buf = NULL;
size_t bufsiz = 0;
if( (my_memstream = open_memstream(&buf, &bufsiz)) == NULL) return 1;
FILE * oldstdout = stdout;
swapfiles(stdout, my_memstream);
hw_c();
swapfiles(stdout, my_memstream);
fclose(my_memstream);
printf("Captured: %s\n", buf);
}
I'm curious if the same is possible for iostreams.
My naive attempt won't compile:
#include <iostream>
#include <string>
#include <sstream>
void hw_cc(){ std::cout<<"hello c++ world\n"; }
int cc_capt(){
using namespace std;
stringstream ss;
string capt;
//std::swap(ss,cout); //<- the compiler doesn't like this
hw_cc();
//std::swap(ss,cout);
cout<<"Captured: "<<capt<<'\n';
}
int main(int argc, char** argv){
c_capt();
puts("---------------------------------");
cc_capt();
return 0;
}
You can, but you don't swap the whole stream--just the stream buffer.
void cc_capt() {
using namespace std;
stringstream ss;
auto orig = std::cout.rdbuf(ss.rdbuf());
hw_cc();
std::cout.rdbuf(orig);
std::cout << "captured: " << ss.str() << "\n";
}
Note that in this case, we're not really using the stringstream itself at all, just the stringbuf it contains. If we wanted, we could just define a basic_stringbuf<char> and use that directly instead of defining a stringstream and then only use the stringbuf it contains.
Based on Jerry's samples, I wrote a template which has one great advantage, it's safe (i.e. if an exception occurs, your buffer gets restored automatically.)
Use this way:
{
ostream_to_buf<char> buf(std::cout);
... run code which `std::cout << "data"` ...
std::string const output(buf.str());
... do something with `output` ...
} // <-- here the buffer is restored
Here is the functional template which I think follows the STL pretty closely. The template is itself an std::stringbuf which inserts itself in the constructor. The destructor restores the original buffer so it is exception safe.
template<
class CharT
, class Traits = std::char_traits<CharT>
, class Allocator = std::allocator<CharT>
>
class ostream_to_buf
: public std::basic_stringbuf<CharT, Traits, Allocator>
{
public:
typedef CharT char_type;
typedef Traits traits_type;
typedef typename Traits::int_type int_type;
typedef typename Traits::pos_type pos_type;
typedef typename Traits::off_type off_type;
typedef Allocator allocator_type;
typedef std::basic_stringbuf<char_type, traits_type, allocator_type> stringbuf_type;
typedef std::basic_ostream<char_type, traits_type> stream_type;
typedef std::basic_streambuf<char_type, traits_type> streambuf_type;
typedef std::basic_string<char_type, traits_type, allocator_type> string_type;
ostream_to_buf<char_type, traits_type, allocator_type>(stream_type & out)
: f_stream(out)
, f_original(f_stream.rdbuf(this))
{
}
ostream_to_buf<char_type, traits_type, allocator_type>(ostream_to_buf<char_type, traits_type, allocator_type> const & rhs) = delete;
ostream_to_buf<char_type, traits_type, allocator_type> & operator = (ostream_to_buf<char_type, traits_type, allocator_type> const & rhs) = delete;
~ostream_to_buf()
{
f_stream.rdbuf(f_original);
}
private:
stream_type & f_stream;
streambuf_type * f_original = nullptr;
};
The copy constructor and assignment operator are deleted because these do not work in this case.
You probably can make it work with C++11 or even C++03. I have C++14 but I don't think any of these require C++14.

Mixing template functions with classes

I'm creating a small logging class that allows a printf-like syntax (courtesy boost::format) using template functions to implement variable-length parameter lists. I think I'm close: after instantiating a Log object 'logger', I want to be able to write logger.Print("This %s is a %s", some_obj, another_obj);. The way I currently have it, this produces the error "No member named 'Print' in 'Log'".
Can anyone suggest what I need to change?
Log.h:
#ifndef LOG_H
#define LOG_H
#include <string>
using std::string;
#include <sstream>
#include <ostream>
#include <fstream>
#include <boost/format.hpp>
enum Severity {
DEBUG,
INFO,
WARN,
CRIT,
DIE,
LEVELS // always last; holds # of severity levels
};
class Log {
public:
Log();
Log(const char*, const char*);
void Print_r(int, const boost::format& );
private:
static const char * sev_code[];
// order is important here!
std::ofstream output_file_stream; // this must be initialized ..
std::ostream& output_stream; // .. before this is bound.
};
int LEVEL; // (where does this belong?)
// This unpacks the variadic arguments one at a time recursively
template <typename T, typename... Params>
void Print_r (int severity, boost::format &boost_format, const T &arg, const Params&... parameters) {
Print_r(severity, boost_format % arg, parameters...); // recursively unpack
}
// This checks severity and converts pat to boost::format
template <typename... Params>
void Print (int severity, const string &pat, const Params&... parameters) {
if (severity < LEVEL) return;
boost::format boost_format(pat);
Print_r(severity, boost_format, parameters...);
}
#endif
Log.cpp:
#include "Log.h"
#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <fstream>
const char * Log::sev_code[] = {
"DBUG",
"INFO",
"WARN",
"CRIT",
"DIE "
};
// Constructor w/no parms = logging to cout
Log::Log() :
output_stream(cout) {
}
// Constructor w/parms = logging to file
Log::Log(const char* dir, const char* file) :
output_stream(output_file_stream) {
string output_file_name = string(dir) + "/" + string(file);
output_file_stream.open(output_file_name.c_str(), std::ofstream::out);
}
// This does the actual logging of the formatted message to the
// output_stream:
void
Log::Print_r (int severity, const boost::format &boost_format) {
std::stringstream s;
s << "[" << sev_code[severity] << "] "
<< boost_format;
output_stream << s << endl;
}
From this code the Print template is outside of the Log class. You need to move it inside the class definition.

C++ preprocesor macro for accumulating comma-separated strings

I need to do the following:
const char* my_var = "Something";
REGISTER(my_var);
const char* my_var2 = "Selse";
REGISTER(my_var2);
...
concst char* all[] = { OUTPUT_REGISTERED }; // inserts: "my_var1, my_var2, ..."
REGISTER and OUTPUT_REGISTERED are preprocesor macros. This would be great for large number of strings, like ~100. Is it possible to accomplish this?
PS. The code belongs to level-0 "block" – i.e. it is not inside any function. AFAIK, I cannot call regular functions there.
#include <iostream>
#include <vector>
using namespace std;
vector<const char*>& all()
{
static vector<const char*> v;
return v;
}
struct string_register
{
string_register(const char* s)
{
all().push_back(s);
}
};
#define REGISTER3(x,y,sr) string_register sr ## y(x)
#define REGISTER2(x,y) REGISTER3(x,y,sr)
#define REGISTER(x) REGISTER2(x, __COUNTER__)
REGISTER("foo");
REGISTER("bar");
int main()
{
}

Data Type Convert

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