c++ custom string format using stringstreams - c++

I am trying to use the new stringstreams method to convert certain float+int combination into certain format but trying to see if there is any better way to handle this:
Now using //string String = static_cast( &(ostringstream() << Number) )->str(); kind of mode - How can I get this stored into a string form of the format - "1.10(3)". Precision is equal to decimals. The catch here is none of these values are constants. Even if the solution can't be an in-line function or stringstreams - it's fine as long as it's generic enough. Also note that in the end the plan is to use this string into GDI text string.
Thanks in advance - if any one can help.
Here is my current sample code(and looking for an alternate efficient way to get this done):
string Convert(float number,int decimals)
{
std::ostringstream buff;
buff<<setprecision(decimals)<<fixed<<number;
return buff.str();
}
float f=1.1; // this can have any values from 1,1.5 or 1.52
int decimals=2; //dynamic number - calculated by other means - not a fixed number
int i=3; // some dynamic number as well - calculated by other means
string s=Convert(f,decimals)+"("+Convert(i,0)+")"; // output - 1.10(3)

You can use std::fixed, std::setprecision, std::setw and std::setfill defined in <iomanip> :
float f=1.1;
int decimals=2;
int i=3;
ostringstream ss;
ss << std::fixed << std::setprecision(decimals) << f << '(' << i << ')';
string str = ss.str();
Which outputs :
1.10(3)
You can also configure the stringstream and keep this configuration :
ostringstream ss;
ss.precision(5);
ss.setf(std::ios::fixed);
EDIT
You can still do this in one line if you really want to :
string str = ((ostringstream&)(ostringstream() << fixed << setprecision(decimals) << f << '(' << i << ')')).str();
If you want a LPCWSTR (const wchar_t *) instead of a LPCSTR (const char*) you should use wstringstream instead of stringstream.
ostringstream ss;
string str = ss.str();
LPCSTR* c_str = str.c_str();
wostringstream wss;
wstring wstr = wss.str();
LPCWSTR* wc_str = wstr.c_str();
If you want a LPCTSTR (LPCSTR or LPCWSTR if UNICODE is defined), you can use some typedef like this :
typedef std::basic_string<TCHAR> tstring;
typedef std::basic_ostringstream<TCHAR , std::char_traits<TCHAR> > tstringstream;
tostringstream tss;
tstring tstr = tss.str();
LPCTSTR* tc_str = tstr.c_str();
TCHAR is a char * if UNICODE is not defined in your project and a wchar_t * if UNICODE is defined.

Related

Changing type of char using wchar_t used not so like L

In my code I tried to create massive of 4 bite chars, where every char contain a Cyrillic letter.
wchar_t OUT_STRING[4] = { L'т',L'л',L'о',L'р' };
All in normal with this and I have expected output. It's only test, in real I need to convert element from string to the same type like in OUT_STRING; I tried to use something like this:
wchar_t OUT_STRING[4] = { (wchar_t)'т',L'л',L'о',L'р' };
But it didn't work and in output I have a rectangle.
I think you want to pass in a string using std::string in UTF-8 encoding and process it one character at a time, each time converting the single character to a wide character string of length 1 so that you can pass it to TTF_SizeUNICODE, and TTF_RenderUNICODE_Blended.
I will demonstrate the relevant string conversion code.
Here is a test function that expects a null-terminated wide character string with just one character in it. The body of main shows how to convert a UTF-8 string to UTF-16 (using codecvt_utf8_utf16) and how to convert a single character to a string (using std::wstring(1, ch))
#include <string>
#include <codecvt>
#include <iostream>
void test(const wchar_t* str) {
std::cout << "Number of characters in string: " << wcslen(str) << std::endl;
for (const wchar_t* ch = str; *ch; ++ch) {
std::cout << ((int)*ch) << std::endl;
}
}
int main() {
std::string input = u8"тлор";
for (wchar_t ch : std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>().from_bytes(input)) {
std::wstring string_with_just_one_character(1, ch);
test(string_with_just_one_character.c_str());
}
return 0;
}

How can i fill a char array with some string , en int

I have a question about a char array:
I have a form '"1"+lapcounter+":"+seconds' that must come in a char array.
How can i fill this array in this form?
Thanks
If you mean you have some numeric variables which you want to format into a string, use a string-stream for that:
std::stringstream ss;
ss << "1" << lapcounter << ":" << seconds";
Now you can extract a string from that:
std::string s = ss.str();
and if you really want a character array for some reason (which I'm sure you don't)
char const * cs = s.c_str();
Use sprintf, or snprintf. This function works similar to printf but instead of standard output, the output will go to char array you specified. For example:
char buffer[32];
snprintf(buffer, sizeof(buffer), "1%d:%d", lapcounter, seconds);
to_string is used like this:
#include <iostream>
#include <string>
int main()
{
int lapcounter = 23;
std::string str("1");
str.append(std::to_string(lapcounter ));
str.append(":seconds");
std::cout << str << std::endl;
}
prints
123:seconds
if you really need a char array you get that from ss.c_str()

How to convert a string to its unicode escapes?

I'm trying to convert a char array to unicode-escapedchar array.
Say I have a string "C:/İmüp".
How can I convert it to C:/\u0130m\u00fcp as char array or const char?
(I get "C:/Hello İmüp" as char array via ExpandEnvironmentStrings(), then i need to write that to a file with its unicode escapes)
I tried typecast converting, std::stringstream and ASCII tables, looked up for examples on C++ json encoders, however i couldn't get it working
Try this:
std::wstring env;
// fill env with data from ExpandEnvironmentStringsW()...
std::stringstream ss;
for (std::wstring::iterator iter = env.begin(); iter != env.end(); ++iter)
{
if (*iter <= 127)
ss << (char) *iter;
else
ss << "\\u" << std::hex << std::setfill('0') << std::setw(4) << (int)*iter;
}
std::string str = ss.str();
// use str as needed...
First convert it from char array to wchar_t array, using the system-default code page.
Then write trivial code that walks over your wchar_t array and escapes every Unicode character with code >= 128.
P.S. Better yet, make your application Unicode so it will use Unicode version of ExpandEnvironmentStrings. This way you will only have to escape the string, plus your app will still work correctly if some environmental string contains a character that doesn’t fit in char with your system-default code page.
Try this code:
string yourAsciiString = "this is test";
string yourUnicodeString = System.Text.Encoding.Unicode.GetString(System.Text.Encoding.ASCII.GetBytes(yourAsciiString));

How to add integer to LPWSTR

I have a function that takes only one LPWSTR as argument. However, I need to add integer to the end of it.
Here's an example pseudocode:
int theNumber = 5;
LPWSTR myLPWSTR = L"Number is: ";
/* Add theNumber to myLPWSTR */
myFunction(myLPWSTR);
How to do this?
I have already tried converting int to LPWSTR and then concatenate them but I didn't succeed. I've tried this for the whole morning but just can't figure out how to do this.
I've tried eg. wsprintf, _itow_s, c_str and pretty much everything I know of - but just can't do it and it's getting really frustrating.
Someone please help.
Assuming the function really takes a LPWSTR and not a LPCWSTR (i.e. it can modify the string passed in), you'll have to do something like this:
int theNumber = 5;
std::wostringstream s;
s << L"Number is: " << theNumber;
std::wstring str = s.str();
std::vector<wchar_t> buf(str.begin(), str.end());
buf.push_back(0);
myFunctions(&buf[0]);
This is necessary because you need to supply a properly nul-terminated and modifiable buffer of wchar_ts. str.c_str() is nul-terminated but not modifiable. &str[0] is modifiable but not (guaranteed to be) nul-terminated.
If you can use C++11:
std::wstring str = L"Number is: ";
str += std::to_wstring(42);
myFunction( str.data() );
if not:
std::wstringstream ss;
ss << L"Number is: " << 42;
myFunction( ss.str().c_str() );
Don't forget to include string and sstream.

How to cast wchar_t into int for displaying the code point?

I have a simple function in my program, when I was wanting to mess around with unicode and do stuff with it. In this function, I wished to display the code value of the character the user entered. It SEEMED possible, here's my function:
wstring listcode(wchar_t arg) {
wstring str = L"";
str += static_cast<int> (arg); //I tried (int) arg as well
str += L": ";
str += (wchar_t) arg;
return str;
}
Now as you see I just wanted to display the integer value (like an ascii character, such as (int) "a"), but something like listcode(L"&") will be displayed as &: & !
Is it not possible to find the integer value of a wide character like that?
In C++, you cannot add anything to strings but characters and other strings. There is no implicit conversion from int (or anything else) to string. That's just the way the string type is designed.
What you do instead is to use string streams:
std::wstring listcode(wchar_t arg)
{
std::wostringstream oss;
oss << static_cast<int>(arg);
oss << L": ";
oss << arg;
return oss.str();
}
In practice, however, when converting to strings in C++, it's better to have functions writing to a stream, than returning a string:
void listcode(std::wostream os, wchar_t arg)
{
os << static_cast<int>(arg);
os << L": ";
os << arg;
}
That way, if you want to output something to the console or to a file, you can directly pass std::cout or a file stream, and if you want a string, you just pass a string stream.