AscW equivalent from VB in C++ - c++

I am using the function AscW (in VB6) to convert a unicode character into the character code.
I would like to know if there is an equivalent to this function in C++.
For example, I would like to get the value 32 from the character " ".
I would like to do the following:
wstring wstringToLower(wstring u)
{
wstring s;
for (int i=0;i<u.size();i++)
{
wstring sChar;
sChar=u.substr(i,1);
int iChar=static_cast<int>(sChar);
int iNewChar=charCodeToLower(iChar);
wstring sNewChar;
sNewChar=wstring(iNewChar,1);
s+=sNewChar;
}
return s;
}
The error "No conversion function found for std::wstring to int" is raised in the line
int iChar=static_cast<int>(sChar);

Cast to int:
int main()
{
std::wstring u = L"abc";
std::wstring sChar = u.substr(1, 1);
for (int i = 0; i < sChar.size(); ++i)
std::cout << static_cast<int>(sChar[i]);
}

Related

Cant compare wide characters | C++

If I read special characters from a file and then try to compare them (like with an if) it doesn't recognize them.
std::wstring c;
std::wifstream file;
file.open("test.txt");
while (file)
{
wchar_t tmp = file.get();
c += tmp;
}
file.close();
size_t l = c.length();
for (int i = 0; i < l; i++)
{
wchar_t a = c[i];
if (a == L'ä') {
std::cout << "if triggered.";
}
}
But when I create a wchar and predefine a special character it does work.
wchar_t a = L'ä';
if (a == L'ä') {
std::cout << "if triggered";
}
and if I put the wstring that was loaded from the file, in the file I get the text back. Nothing weird happens there.
This depends on the kind of file encoding.
I would implicitly say that, in this case, UTF-8.
The code below may be work fine:
std::string str;
{
std::ifstream file;
file.open("D:/test.txt");
file >> str;
}
wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
wstring wstr = myconv.from_bytes(str);
size_t l = wstr.length();
for (int i = 0; i < l; i++)
{
auto a = wstr[i];
if (a == L'ä') {
std::cout << "if triggered.";
}
}
However, std::codecvt_utf8 is deprecated in C++17
For the cases using higher C++17:
By MSVC++
I recommend using CString, it's too easy and worked on every almost version of C++, follow this:
std::string str;
{
std::ifstream file;
file.open("D:/test.txt");
file >> str;
}
CString wstr = (CString)CA2W(str.c_str(), CP_UTF8);
size_t l = wstr.GetLength();
for (int i = 0; i < l; i++)
{
auto a = wstr[i];
if (a == L'ä') {
std::cout << "if triggered.";
}
}
#include <atlstr.h> for non-MFC

How to split LPWSTR with multiple delimiters & return array of LPWSTR in c++?

I need to split LPWSTR with multiple delimiters & return array of LPWSTR in c++. How to do it?
I tried to do from the following question:
How to split char pointer with multiple delimiters & return array of char pointers in c++?
But it prints ?? for each wstring. What's wrong with it?
can I do it as I tried follow? If so what's the mistake I made? If not how to do it?
std::vector<wstring> splitManyW(const wstring &original, const wstring &delimiters)
{
std::wstringstream stream(original);
std::wstring line;
vector <wstring> wordVector;
while (std::getline(stream, line))
{
std::size_t prev = 0, pos;
while ((pos = line.find_first_of(delimiters, prev)) != std::wstring::npos)
{
if (pos > prev)
{
wstring toPush = line.substr(prev, pos-prev);
//wstring toPushW = toWide(toPush);
wordVector.push_back(toPush);
}
prev = pos + 1;
}
if (prev < line.length())
{
wstring toPush = line.substr(prev, std::wstring::npos);
//wstring toPushW = toWide(toPush);
wordVector.push_back(toPush);
}
}
for (int i = 0; i< wordVector.size(); i++)
{
//cout << wordVector[i] << endl;
wprintf(L"Event message string: %s\n", wordVector[i]);
}
return wordVector;
}
int main()
{
wstring original = L"This:is\nmy:tst?why I hate";
wstring separators = L":? \n";
vector<wstring> results = splitManyW(original, separators);
getchar();
}
You're not properly accessing the wchar_t* exposed from std::wstring when you print your final tokens. Further, your output format specifier is incorrect. Per the wprintf documentation (see here), in particular "If the l specifier is used, the argument must be a pointer to the initial element of an array of wchar_t.".
A few modifications and stripping out some redundancies gives the following:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using std::wstring;
using std::vector;
std::vector<wstring> splitManyW(const wstring &original, const wstring &delimiters)
{
std::wstringstream stream(original);
std::wstring line;
vector <wstring> wordVector;
while (std::getline(stream, line))
{
std::size_t prev = 0, pos;
while ((pos = line.find_first_of(delimiters, prev)) != std::wstring::npos)
{
if (pos > prev)
wordVector.emplace_back(line.substr(prev, pos-prev));
prev = pos + 1;
}
if (prev < line.length())
wordVector.emplace_back(line.substr(prev, std::wstring::npos));
}
return wordVector;
}
int main()
{
wstring original = L"This:is\nmy:tst?why I hate";
wstring separators = L":? \n";
vector<wstring> results = splitManyW(original, separators);
for (auto const& w : results)
wprintf(L"Event message string: %ls\n", w.c_str());
getchar();
}
Output
Event message string: This
Event message string: is
Event message string: my
Event message string: tst
Event message string: why
Event message string: I
Event message string: hate
Note: I would have preferred using formatted stream output using operator <<, but that is somewhat unrelated to your question.
Best of luck.
You should have executed it under a debugger. You would have seen immediately that your parsing is correct, so is your vector.
The problem is that you are trying to use to old C wprintf with format %s which expects a C string (a null terminated char array), and you pass a std::string which is a totally different object.
You can either :
do it the C way, getting the C string contained by the std::string:
wprintf(L"Event message string: %s\n", wordVector[i].c_str());
do it the C++ way, using wcout:
wcout << L"Event message string: " << wordVector[i] << std::endl;
But your return value is not an array of LPWSTR but a vector of std::string.
You should first allocate the array of pointers to char array, then individually allocate the char arrays, return that... and do not forget to free everything.
LPWSTR is wchar_t*, so basically what you need is wcstok.

C++ SDL 2.0 - Importing multiple textures using a loop

I don't know whether or not this is possible but I have used this technique in different languages but am struggling to use it in C++. I have 10 images that I am trying to load into an array using a loop as so:
for (int i = 0; i < 10; i++)
{
Sprite[i] = IMG_LoadTexture(renderer, "Graphics/Player" + i + ".png");
}
This however does not seem to work in C++ so I was wondering what I am doing wrong, or what can I do to get the same result without having to load each image individually like so:
Sprite[0] = IMG_LoadTexture(renderer, "Graphics/Player0.png");
My error is: "Expression must have integral or unscoped enum type"
Thanks for any help =)
You cannot do this:
"This is my number: " + (int)4 + "!";
This is illegal. It will give you an error for trying to operator+ a const char* and a const char[SOME_INT_GOES_HERE] or another error for trying to use operator+ to add an int onto a string. Things just don't work that way.
You'd either have to use C (i.e. snprintf()) or a string stream. Here's my test code for isolating your problem:
#include <iostream>
#include <string>
int main()
{
int a = 1;
std::string str = "blah";
std::string end = "!";
//std::string hello = str + a + end;// GIVES AN ERROR for operator+
std::string hello = "blah" + a + "!";
//const char* c_str = "blah" + a + "end";
//std::cout << c_str << std::endl;
std::cout << hello << std::endl;
return 0;
}
Here's an alternative solution using string streams.
#include <iostream>
#include <string>
#include <sstream>
int main()
{
int i = 0;
std::string str;
std::stringstream ss;
while (i < 10)
{
//Send text to string stream.
ss << "text" << i;
//Set string to the text inside string stream
str = ss.str();
//Print out the string
std::cout << str << std::endl;
//ss.clear() doesn't work. Calling a constructor
//for std::string() and setting ss.str(std::string())
//will set the string stream to an empty string.
ss.str(std::string());
//Remember to increment the variable inside of while{}
++i;
}
}
Alternatively, you can also use std::to_string() if you're using C++11 (which just requires -std=c++11) but std::to_string() is broken on some sets of compilers (i.e. regular MinGW). Either switch to another flavor where it works (i.e. MinGW-w64) or just write your own to_string() function using string streams behind the scenes.
snprintf() may be the fastest way of doing such a thing, but for safer C++ and better style, it is recommended you use a non-C way of doing things.
I had a similar problem and I solwed it this way:
#include <iostream>
using namespace std;
int main() {
string line;
for (int i = 0; i < 10; i++) {
line = "Graphics/Player" + inttostr(i) + ".png"; //I wrote inttostr function because built in inttostr functions messed up my program (see below)
char charger[line.length()]; //creating char array
for (int i = 0; i < sizeof(line); i++) {
charger[i] = line[i]; // copying string to char arry
}
Sprite[i] = IMG_LoadTexture(renderer, charger);
}
}
string inttostr(int integer) { //I know it isn't the best way to convert integer to string, but it works
string charakter;
int swap;
bool negativ = false;
if (integer < 0) {
integer = -integer;
negativ = true;
}
if (integer == 0) {
charakter = "0";
}
while (integer >= 1) {
swap = integer % 10;
integer = integer / 10;
charakter = char(swap + 48) + charakter;
}
if (negativ) {
charakter = "-" + charakter;
}
return charakter;
}

Conversion from string to Ice::ByteSeq

I gotta question about Ice in C++. One of my methods requires that I pass in a Ice::ByteSeq. I would like to build this ByteSeq from a string. How is this conversion possible?
I tried the options below.
Ice::ByteSeq("bytes") // Invalid conversion to unsigned int
Ice::ByteSeq((byte*)"bytes") // Invalid conversion from byte* to unsigned int
(Ice::ByteSeq)"bytes" // Invalid conversion from const char& to unsigned int
(Ice::ByteSeq)(unsigned int)atoi("bytes") // Blank (obviously, why did I try this?)
How can I make this happen?
EDIT
"bytes" is a placeholder value. My actualy string is non-numeric text information.
Looking at the header, ByteSeq is an alias for vector<Byte>. You can initialise that from a std::string in the usual way
std::string s = "whatever";
Ice::ByteSeq bs(s.begin(), s.end());
or from a string literal with a bit more flappery, such as
template <size_t N>
Ice::ByteSeq byteseq_from_literal(char (&s)[N]) {
return Ice::ByteSeq(s, s+N-1); // assuming you don't want to include the terminator
}
Ice::ByteSeq bs = byteseq_from_literal("whatever");
You were almost there,
Ice::ByteSeq((unsigned int)atoi("bytes"));
should do it
Assuming your Ice::ByteSeq has a constructor that takes unsigned int
To split this down, it's basically doing
int num = atoi("12345"); // num = (int) 12345
unsigned int num2 = (unsigned int)num; // num2 = (unsigned int) 12345
Ice::ByteSeq(num2);
If Ice::ByteSeq is simply a vector of bytes you can convert a string to a vector of bytes by doing a variation of the following:
std::string str = "Hello World";
std::vector<char> bytes(str.begin(), str.end());
The implementation of Ice::Byte is an unsigned char just change the standard code I posted from:
std::vector<char> bytes(str.begin(), str.end());
to
std::vector<unsigned char> bytes(str.begin(), str.end());
and the generated vector should be directly compatible with an Ice::ByteSeq
sample code:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::string str = "Hello World";
std::vector<unsigned char> bytes(str.begin(), str.end());
cout << str << endl;
for(int i=0; i < bytes.size(); i++)
std::cout << bytes[i] << '\n';
return 0;
}
Hope this helps:)

Whats wrong with this c++ reverse string function

void reverse (char s[]){
int len = strlen(s);
int j = len - 1;
for (int i = 0; i < j; i++,j--){
cout << s[i];
char ch = s[i];
s[i] = s[j]; //error line - giving exception, cannot write to the memory
s[j] = ch;
}
}
I am using Visual Studion 2008 and i can't understand whats the problem here .. :s .. I am out of C++ practice :$ .
The problem is that it uses C-style strings instead of C++ style strings. In particular, you are apparently trying to write to a constant string literal:
char const* str = "I cannot be written to";
C++ allows to omit the const here for backwards compatibility but the literal is still constant.
Finally, C++ already has a reverse function:
#include <algorithm>
#include <iostream>
#include <string>
int main() {
std::string str = "Hello world";
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
}
I'd guess the problem is with how you're calling it, probably with a string literal, something like:
reverse("This is a string");
or:
char *string = "This is a string";
reverse(string);
or some other minor variation. In any case, you're trying to write to a string literal, which gives undefined behavior.
Since you're apparently using C++, I'd consider using an std::string instead:
void reverse(std::string &s) {
int j=s.length()-1;
for (int i=0; i<j; i++, j--) {
// ..
}
}
Are you calling this on a const char* or a string literal?
Are you trying to reverse
reverse("foo");
or
char *s = "foo";
reverse(s);
You'll need to create a new string from the non-writeable one and reverse that instead. You can use strdup.
char *s = strdup("foo");
reverse(s);
free(s, strlen(s));
Also note that your question is tagged c++, so you should probably be using std::string.