C++ create empty byte - c++

I was wondering if you could help me with a small problem I have:
I am currently devloping in C++/Qt and got the following error message:
P:\Produkt\Savor_V100\webapi.cpp:84: error: C2664: 'CryptoPP::PasswordBasedKeyDerivationFunction::DeriveKey' : cannot convert parameter 1 from 'const char *' to 'byte *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
The parameter in the function is not used, therefore I would like to pass an empty byte in there. After a bit of research I found out that a byte is just a simple unsigned char?
My code looks like this:
byte* unused;
qDebug() << CryptoPP::PasswordBasedKeyDerivationFunction::DeriveKey(CryptoPP::SHA1::StaticAlgorithmName(), CryptoPP::SHA1::BLOCKSIZE, unused, user->getPassword(), sizeof(user->getPassword()), user->getSerial(), sizeof(user->getSerial()), 0 );

As said in the comment, the issue here is with the first argument of the function, not with the third where you used unused. Since I guess you do need this parameter, you should try as suggested:
qDebug() << CryptoPP::PasswordBasedKeyDerivationFunction::DeriveKey(
reinterpret_cast<byte*>(CryptoPP::SHA1::StaticAlgorithmName()),
CryptoPP::SHA1::BLOCKSIZE,
0,
user->getPassword(),
sizeof(user->getPassword()),
user->getSerial(),
sizeof(user->getSerial()),
0 );

Related

C++ convert std::string to char

I have following scenario:
struct MyStruct
{
char name[25];
char address[12];
}
Somewhere::SomeMethod(std::shared_ptr<SomeArgumentClass> args)
{
// GetName() and GetAddress() both return std::strings
::MyStruct newValue = {args->GetName(), args->GetAddress()};
// add newValue to some structure that needs to have chars
}
Error:
error C2440: 'initializing' : cannot convert from 'std::string' to 'char'
error C2440: 'initializing' : cannot convert from 'std::string' to 'char'
I am not able to get my std::string converted to a char.
Thanks a lot!
Firstly, your terminology is incorrect. You don't want to convert to char, which is a single character. I realise that the error message claims you're trying to convert to char, but that's because your incorrect code has confused the compiler into thinking you're trying to initialise individual elements of the array name. Be wary of the specifics of an error message when you write the wrong code, because the compiler cannot read your mind — it can only go off of what you've written!
In reality you want to copy the characters inside your std::string, into the array of char, that is your member.
Like so:
Somewhere::SomeMethod(std::shared_ptr<SomeArgumentClass> args)
{
const auto& name = args->GetName();
const auto& address = args->GetAddress();
::MyStruct newValue;
std::copy(std::begin(name), std::end(name), &newValue.name[0]);
std::copy(std::begin(address), std::end(address), &newValue.address[0]);
// add newValue to some structure that needs to have chars
}
But you need to add bounds checking too. To do that, roughly I might consider replacing each std::copy call with something like:
std::copy_n(
&name[0],
std::min(name.size(), sizeof(newValue.name)),
&newValue.name[0]
);
You'll also need some null termination depending on how many characters were copied.
Generally though the salient point is that you need to actually copy those characters because there is no one-step way to do it. It stems in part from how arrays can't be assigned-to, but also from the fact that their dimensions are part of the type which makes things more complicated.
If this seems like a pain in the arse, that's because it is — ideally you would stick with std::string across the board because it's far superior, and was specifically introduced to make it easier to handle arrays of char. You can still pass a const char* (or char*!) pointing to the string's data into a C API. Of course if ::MyStruct itself is a third-party C type, you have no choice but to do it the hard way.

How to construct WebURL from std::wstring?

I am writing a Win32 application with Awesomium. According to the tutorial section I can load a local file inside my view:
WebURL url(WSLit("file:///C:/dev/project/util/ui/index.html"));
view_->web_view()->LoadURL(url);
This works as expected.
When I try to pass an std::wstring to WSList function:
std::wstring ui_path = L"file:///" + install_path + L"/util/ui/index.html";
WebURL url(WSLit(ui_path));
view_->web_view()->LoadURL(url);
I get a compiler error:
src/main.cc(52) : error C2664: 'Awesomium::WSLit' : cannot convert parameter 1 from
'std::wstring' to 'const char *' No user-defined-conversion operator available that can
perform this conversion, or the operator cannot be called
When I try to pass WSLit( ui_path.c_str() ) the compiler throws another error:
src/main.cc(52) : error C2664: 'Awesomium::WSLit' : cannot convert parameter 1 from
'const wchar_t *' to 'const char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or
function-style cast
What is the right way to convert it to const char * type?
Edit:
From Awesomium documentation :
WSLit() is a special helper function that lets you declare WebString literals. Most of our API uses UTF-16 strings (wrapped with WebString) but we added WSLit() so you can declare ASCII C-strings with minimal fuss.
WSLit is meant to construct a WebString object from an ASCII string. Since you don't want to construct a WebString from ASCII, but rather have a UNICODE string from the beginning, you simply don't need to use WSLit at all.
The following line of code constructs a WebURL from a std::wstring:
WebURL url(WebString(ui_path.c_str()));
As pointed out by Remy Lebeau this may not compile for any given compiler or compiler settings. WebString has an explicit constructor taking a const wchar16*. Platform.h defines wchar16 as
typedef unsigned short wchar16;
Depending on your compiler and compiler settings, this may or may not be the same as wchar_t. When compiling with the Microsoft compiler using the command line option /Zc:wchar_t, wchar_t is interpreted as a native data type. This is a different type from unsigned short, and the explicit constructor of WebString requires an additional cast:
WebURL url(WebString(reinterpret_cast<const wchar16*>(ui_path.c_str())));
Implicitly invoking the conversion constructor of WebString using the following syntax is not possible, since it is declared explicit:
WebURL url(reinterpret_cast<const wchar16*>(ui_path.c_str()));
If the question is "convert std::wstring to const char*", I usually use this function and it works fine:
std::string wstringToString(const std::wstring& in){
std::string result(in.begin(), in.end());
return result;
}
And then, you can get char* by calling result.c_str();
Try this one:
std::wstring ui_path = L"file:///" + install_path + L"/util/ui/index.html";
std::string cui_path( ui_path.begin(), ui_path.end() );
WebURL url(WSLit(cui_path));
view_->web_view()->LoadURL(url);
However, IMHO, if Awesomium is intended to run under Windows, the WSLit constructor should support either a std::wstring or wchar_t * argument.

Unable to create an array of wchar_t

In my code I have an array of wchar_t:
wchar_t paths [6] = {L"C:\\Program Files\\SomeAppsSuiteFolder1", L"C:\\Program Files\\SomeAppsSuiteFolder2", L"C:\\Program Files (x86)\\SomeAppsSuiteFolder1", L"C:\\Program Files (x86)\\SomeAppsSuiteFolder2", L"C:\\SomeAppsSuiteFolder1", L"C:\\SomeAppsSuiteFolder2"};
Later on I use the array in for loop. The problem is, that for this line I get following errors:
error: too many initializers for 'wchar_t [6]'
error: initializer-string for array of chars is too long [-fpermissive]
What's more, in for loop I have if conditional like this one:
if(GetFileAttributesW(paths[i])!=INVALID_FILE_ATTRIBUTES) {...}
And, again, I get an error here:
error: invalid conversion from 'wchar_t' to 'LPCWSTR {aka const wchar_t*}' [-fpermissive]
Strange enough, similar code used to compile correctly some months ago... What's the problem?
You need
const wchar_t* paths[6] = ....
You need to use:
wchar_t *paths[6] = ...
^
A wchar_t is a single (wide) character, not a string of them.
So, if you want an array of wide strings, you should use the pointer variant.
The declarator wchar_t xyzzy[6] gives you six characters rather than six character arrays.

How to add strings to a 2d array of char elements?

I have the below program written in C++:
#include <iostream>
using namespace std;
int main()
{
int age[5];
char name[5][10];
age[0]=10;
age[1]=20;
age[2]=30;
age[3]=25;
age[4]=40;
name[0]="abc";
name[1]="abc";
name[2]="abc";
name[3]="abc";
name[4]="abc";
cout<<name[0]<<" is "<<age[0]<<"years old";
cout<<"\n";
cout<<name[1]<<" is "<<age[1]<<"years old";
cout<<"\n";
cout<<name[2]<<" is "<<age[2]<<"years old";
cout<<"\n";
cout<<name[3]<<" is "<<age[3]<<"years old";
cout<<"\n";
cout<<name[4]<<" is "<<age[4]<<"years old";
cout<<"\n\n";
system("PAUSE");
}
When I compile and run it, I get these errors:
error C2440: '=' : cannot convert
from 'const char [3]' to 'char [10]'
There is no context in which this conversion is possible
error C2440: '=' : cannot convert
from 'const char [2]' to 'char [10]'
There is no context in which this conversion is possible
error C2440: '=' : cannot convert
from 'const char [2]' to 'char [10]'
There is no context in which this conversion is possible
error C2440: '=' : cannot convert
from 'const char [2]' to 'char [10]'
There is no context in which this conversion is possible
error C2440: '=' : cannot convert
from 'const char [2]' to 'char [10]'
There is no context in which this conversion is possible
I am running MSVC 2008 under Windows 7. I have tried many possible solutions but I failed in fixing this. Any help would be appreciated,
You are treating the name array as if it was defined thus:
char *name[5];
So either define it that way, or use the following code to populate it:
strcpy(name[0], "abc");
strcpy(name[1], "abc");
strcpy(name[2], "abc");
strcpy(name[3], "abc");
strcpy(name[4], "abc");
I prefer the former choice. The point being you are trying to assign a char * to a char [] which is what strcpy is for. Given you are manipulating initialized C strings in this case anyway, you might as well deal with char * throughout the code.
You should use std::string for this purpose. The use of char* and char[] to represent strings is deprecated in C++ for many good reasons.
Given the program snippet, name can be initialized at the declaration itself.
char name[5][10] = { "abc", "abc", "abc", "abc", "abc" } ;
// ^ index 5 is not necessary. char name[][10] = { .. } would also suffice.
Specified the length of each row is 10 but only using first 3 indexes of it. Every 3rd index ( i.e., 4th element in the array ) is automatically added with a '\0'.
Initialization can be done in case of age array too.
You can use also std::string name[10] instead of 2d char's array. In this case only you can assign new values to the strings through operator '='.
Otherwise you should to use array of char* and use strcpy() function for assignment.

Error with strcpy and its second argument

When I try and compile this program, I get errors (included below the code) about strcpy's second argument. I'm honestly stumped on what to do to fix it. And I'm sorry if my code is not efficient or pretty to look at; I'm just a beginning CS student.
#include "stdafx.h"
#include <iostream>
#include <ctime>
using namespace std;
int main(){
int r = 0;
char *article[]={"the", "a", "one", "some", "any"};
char *noun[]={"boy","girl","dog","town","car"};
char *verb[]={"drove","jumped","ran","walked","skipped"};
char *preposition[]={"to","from","over","under","on"};
char sentence [80];
srand(time(NULL));
for(int i=0;i<=20;i++){
r = (rand()%5);
strcpy(sentence,*article[r]);
strcat(sentence," ");
r = (rand()%5);
strcat(sentence,*noun[r]);
strcat(sentence," ");
r = (rand()%5);
strcat(sentence,*verb[r]);
strcat(sentence," ");
r = (rand()%5);
strcat(sentence,*preposition[r]);
strcat(sentence," ");
r = (rand()%5);
strcat(sentence,*article[r]);
strcat(sentence," ");
r = (rand()%5);
strcat(sentence,*noun[r]);
strcat(sentence,".");
}
sentence[0]= toupper(sentence[0]);
cout<<sentence <<endl;
system("pause");
return 0;}
1>Compiling...
1>assignment 8.cpp
1>e:\assignment 8\assignment 8\assignment 8.cpp(16) : warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
1>e:\assignment 8\assignment 8\assignment 8.cpp(20) : error C2664: 'strcpy' : cannot convert parameter 2 from 'char' to 'const char *'
1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
1>e:\assignment 8\assignment 8\assignment 8.cpp(23) : error C2664: 'strcat' : cannot convert parameter 2 from 'char' to 'const char *'
1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
1>e:\assignment 8\assignment 8\assignment 8.cpp(26) : error C2664: 'strcat' : cannot convert parameter 2 from 'char' to 'const char *'
1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
1>e:\assignment 8\assignment 8\assignment 8.cpp(29) : error C2664: 'strcat' : cannot convert parameter 2 from 'char' to 'const char *'
1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
1>e:\assignment 8\assignment 8\assignment 8.cpp(32) : error C2664: 'strcat' : cannot convert parameter 2 from 'char' to 'const char *'
1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
1>e:\assignment 8\assignment 8\assignment 8.cpp(35) : error C2664: 'strcat' : cannot convert parameter 2 from 'char' to 'const char *'
1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
DANGER. strcat() AND strcpy() ARE THE LEADING CAUSES OF CODE CANCER. Using them exposes you to all kinds of buffer overflows. Use strncat()/strncpy(), or (even better) just use std::string, since you're using C++!
strcat() and strcpy() expect their arguments to be strings. *article[r] is a single char--article[r] is the string you want. So, drop the leading asterisks.
You have one asterisk too many - noun[r] already gives you a char* so you don't need to put an additional * in the second parameter.
Also, strcat is an unsafe function and can crash your program unexpectedly if your buffer (in your case, sentence) is ever too small for the content.
Please use strncat instead - you'll need to add one more parameter to that function, which is the buffer size - in this case, 80. Then in case of undersized buffer instead of program crash you would just notice that your sentence is clipped at the end.
Your articles, nouns, and verbs are arrays of char pointers. When selecting the item in the array to use, you get a char* to the word to use. This char* is what strcpy expects - when you dereference the char* (i.e. article[r]), you end up with a char, not a char.
Also, strcpy is an unsafe string operator, so it can overwrite large clumps of memory or otherwise open gaping security holes. Is there any reason you're not allowed to use std::string for this assignment?
Too much de-referencing, e.g. change:
strcpy(sentence,*article[r]);
to
strcpy(sentence, article[r]);
and similarly for the other instances.
*article[r] is a value of type char. It's the first character of the string. strcpy expects the address of the string which is simply article[r].
Instead of
strcpy(sentence,*article[r]);
you want
strcpy(sentence,article[r]);