In a multibyte project (vs2017):
#ifndef _TCHAR_DEFINED
typedef char TCHAR;
typedef char * PTCHAR;
typedef unsigned char TBYTE;
typedef unsigned char * PTBYTE;
#define _TCHAR_DEFINED
struct _getopt_data
{
/* These have exactly the same meaning as the corresponding global
variables, except that they are used for the reentrant
versions of getopt. */
int optind;
int opterr;
int optopt;
TCHAR *optarg;
/* Internal members. */
/* True if the internal members have been initialized. */
int __initialized;
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
TCHAR *__nextchar;
/* Describe how to deal with options that follow non-option ARGV-elements.
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters.
PERMUTE is the default. We permute the contents of ARGV as we
scan, so that eventually all the non-options are at the end.
This allows options to be given in any order, even with programs
that were not written to expect this.
RETURN_IN_ORDER is an option available to programs that were
written to expect options and other ARGV-elements in any order
and that care about the ordering of the two. We describe each
non-option ARGV-element as if it were the argument of an option
with character code 1. Using `-' as the first character of the
list of option characters selects this mode of operation.
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} __ordering;
/* If the POSIXLY_CORRECT environment variable is set. */
int __posixly_correct;
/* Handle permutation of arguments. */
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first
of them; `last_nonopt' is the index after the last of them. */
int __first_nonopt;
int __last_nonopt;
#if defined _LIBC && defined USE_NONOPTION_FLAGS
int __nonoption_flags_max_len;
int __nonoption_flags_len;
# endif
};
int
_getopt_internal_r(int argc, TCHAR *const *argv, const TCHAR *optstring,
const struct option *longopts, int *longind,
int long_only, struct _getopt_data *d, int posixly_correct)
{
...
TCHAR c = *d->__nextchar++;
TCHAR *temp = _tcschr(optstring, c); // <= cannot convert from 'const char *' to 'TCHAR *' (first parameter)
...
}
Everything looks correct; in tchar.h:
#define _PUC unsigned char *
#define _CPUC const unsigned char *
#define _PC char *
#define _CRPC _CONST_RETURN char *
#define _CPC const char *
#define _UI unsigned int
/* String functions */
__inline _CRPC _tcschr(_In_z_ _CPC _s1,_In_ _UI _c) {return (_CRPC)_mbschr((_CPUC)_s1,_c);}
Why is _tcschr() complaining that a parameter is not of const char*, when it is?
In C++, _tcschr() is overloaded to take either a TCHAR* or a const TCHAR* as input. To return a non-const TCHAR*, you will have to call the non-const overload, which means casting away the const off of optstring, eg:
TCHAR *temp = _tcschr(const_cast<TCHAR*>(optstring), c);
Or else define _CONST_RETURN, per the documentation:
In C, these functions take a const pointer for the first argument. In C++, two overloads are available. The overload taking a pointer to const returns a pointer to const; the version that takes a pointer to non-const returns a pointer to non-const. The macro _CRT_CONST_CORRECT_OVERLOADS is defined if both the const and non-const versions of these functions are available. If you require the non-const behavior for both C++ overloads, define the symbol _CONST_RETURN.
Related
So i have this function which receives a pointer:
int myfunc( const char *token, unsigned char *plaintext )
I do my stuff and i end up with a char array:
unsigned char my_plaintext[1024];
Now i need to set that pointer (plaintext) to what's in my_plaintext.
I've tried many different ways but i haven't yet figure this one out...
This part is in a cpp file, and i've even tried:
std::string tmpstr( my_plaintext );
But this comes back with:
token_crypto.cpp:131:13: error: invalid conversion from 'char*' to 'unsigned char*' [-fpermissive]
my_plaintext
^~~~~~~~~~~~
And
std::string tmpstr( (char *)my_plaintext );
'�5�B'
this does compiles but the content is all wrong:
EDIT:
The content of my_plaintext is fine:
int myfunc( const char *token, unsigned char *plaintext ) {
unsigned char my_plaintext[1024];
... some processing stuff (specifically gcm_decrypt) to which is pass my_plaintext ...
cout << my_plaintext
// prints: hello:world
but then however i try set the contents of plaintext to whatever is in my_plaintext either fails at compilation or prints some weird characters.
If you know that plaintext already points at an array that is 1024 long (or longer) then you can use memmove():
int myfunc( const char *token, unsigned char *plaintext )
{
unsigned char my_plaintext[1024];
/* ... fill in my_plaintext here ... */
memmove(plaintext, my_plaintext, 1024);
/* ... rest of function ... */
}
Note that the parameters to memmove are destintation and then source rather than the other way round.
It's up to the caller of your function to make sure the pointer they pass in points to at least 1024 bytes.
You can use memcpy() instead in this case, but using memmove() is good practice in general.
The C++ string constructor doesn't take an unsigned char *. See the C++ reference here:
http://www.cplusplus.com/reference/string/string/string/
You need to cast the unsigned char array to a char array. See how to do that here:
How to Convert unsigned char* to std::string in C++?
The most similar thing I found is conversion to char. I'm trying to convert TCHAR "path" to const char. Btw I use character set: "Not Set".
#include <stdlib.h>
// ... your defines
#define MAX_LEN 100
TCHAR *systemDrive = getenv("systemDrive");
TCHAR path[_MAX_PATH];
_tcscpy(path, systemDrive);
TCHAR c_wPath[MAX_LEN] = _T("Hello world!");//this is original
//TCHAR c_wPath[MAX_LEN] = path; "path" shows error
char c_szPath[MAX_LEN];
wcstombs(c_szPath, c_wPath, wcslen(c_wPath) + 1);
TCHAR is alias for different types depending of platform, defined macros, etc.
so, TCHAR can be alias for char(1 byte) or WCHAR(2 bytes).
further, WCHAR can be alias for wchar_t or unsigned short.
But, you made conversion using wcstombs which has signature like
size_t wcstombs(char *, const wchar_t *, size_t),
so you have
char* c_szPath
pointing to converted array of char,
now, if you need const char*, it is probably enough to write simply
const char * myPath = c_szPath, it is legal, and use myPath.
But maybe, you even don't need this, because char* can bind on argument of type
const char * if you need to pass it to function as argument.
When you say,
"path" shows error
that is because array type is not assignable.
I really hope this helps.
I'm doing a school assignment where I have to call execvp, whose method signature is the following
execvp(const char* file, char* const argv[])
However my data is in the form:
std::vector<std::string*>
I've been trying to convert said vector into the right format for the second format of execvp(), but inevitably get the following error:
command.cc:120:29: error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]
execvp(args[0], argv);
I've tried different variations but they all lead to this error. This error confuses me, since I have no idea what it means by const*. How can you have a const*? I'd consider changing the std::vector to some other type, but this is an assignment and I'm not really allowed to change it. Below is the code I use to try and create a char*[] from the vector:
const size_t numArgs = _simpleCommands[i]->_arguments.size();
std::vector<const char*> args;
for(size_t j = 0; j < numArgs; ++j)
{
args.push_back(strPtrToCharPtr(_simpleCommands[i]->_arguments[i]));
}
const char** argv = new const char*[numArgs];
for(size_t j = 0; j < numArgs; ++j)
{
argv[j] = args[j];
}
execvp(args[0], argv);
The char* const argv[] prototype means that argv is (the address of) an array of pointers to char, that the pointers in the array cannot be modified, but that the strings they point to can be. This is different from a char const **, which is a pointer to a pointer to char whose characters cannot be modified. Since passing it to a function that might modify the strings in the array would violate the const qualifier of const char **, it is not allowed. (You could do it with const_cast, but that would be solving the wrong problem.)
Since execvp() is a very old UNIX function and would not have the same interface today, it doesn’t have any parameter to tell the OS how many arguments there are, nor does it promise not to modify the contents of the strings in the array. You terminate the array by setting the final element to NULL.
It’s a similar format to the argv parameter of main(). In fact, it becomes the argv parameter of the main() function of the program you run, if it was written in C.
This isn’t a complete solution, since this is a homework assignment and you want to solve it on your own, but you have to create that array yourself. You can do this by creating a std::vector<char *> argv( args.size() + 1 ), setting each element but the last to the .data() pointer from the corresponding element of args, and setting the last element to NULL. Then, pass argv.data() to execvp().
Note that the POSIX.1-2008 standard says,
The argv[] and envp[] arrays of pointers and the strings to which those arrays point shall not be modified by a call to one of the exec functions, except as a consequence of replacing the process image.
Therefore, you ought to be able to get away with casting away the const-ness of the strings in the array, this once, if you don’t mind living dangerously. Normally, you would need to make a modifiable copy of each constant string in the array.
Update
Enough time has passed that I’m not giving out answers to homework. A commenter claimed that my answer did not work on g++8, which means that they didn’t implement the same algorithm I was thinking of. Therefore, posting the complete solution will be helpful.
This actually solves the closely-related problem of how to convert a std::vector<std::string> for use with execvp(). (A std::vector<std::string*> is basically never correct, and certainly not here. If you really, truly want one, change the type of s in the for loop and dereference.)
#define _XOPEN_SOURCE 700
// The next three lines are defensive coding:
#define _POSIX_C_SOURCE 200809L
#define _XOPEN_VERSION 700
#define _XOPEN_UNIX 1
#include <errno.h>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <vector>
int main()
{
const std::vector<std::string> cmdline{ "ls", "-al" };
std::vector<const char*> argv;
for ( const auto& s : cmdline ) {
argv.push_back( s.data() );
}
argv.push_back(NULL);
argv.shrink_to_fit();
errno = 0;
/* Casting away the const qualifier on the argument list to execvp() is safe
* because POSIX specifies: "The argv[] [...] arrays of pointers and the
* strings to which those arrays point shall not be modified by a call to
* one of the exec functions[.]"
*/
execvp( "/bin/ls", const_cast<char* const *>(argv.data()) );
// If this line is reached, execvp() failed.
perror("Error executing /bin/ls");
return EXIT_FAILURE;
}
Another twist on this would be to write a conversion function that returns the std::vector<const char*> containing the command-line arguments. This is equally efficient, thanks to guaranteed copy elision. I normally like to code using RIIA and static single assignments, so I find it more elegant to return an object whose lifetime is managed automatically. In this case, the elements of argv are weak references to the strings in cmdline, so cmdline must outlive argv. Because we used C-style pointers as weak references, RIIA does not quite work here and we still need to pay attention to object lifetimes.
#define _XOPEN_SOURCE 700
#define _POSIX_C_SOURCE 200809L
#define _XOPEN_VERSION 700
#define _XOPEN_UNIX 1
#include <errno.h>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <vector>
std::vector<const char*> make_argv( std::vector<std::string>const& in )
{
std::vector<const char*> out;
out.reserve( in.size() + 1 );
for ( const auto& s : in ) {
out.push_back( s.data() );
}
out.push_back(NULL);
out.shrink_to_fit();
return out; // Benefits from guaranteed copy elision.
}
int main()
{
const std::vector<std::string> cmdline{ "ls", "-al" };
errno = 0;
/* Casting away the const qualifier on the argument list to execvp() is safe
* because POSIX specifies: "The argv[] [...] arrays of pointers and the
* strings to which those arrays point shall not be modified by a call to
* one of the exec functions[.]"
*/
execvp( "/bin/ls", const_cast<char* const *>(make_argv(cmdline).data()) );
// If this line is reached, execvp() failed.
perror("Error executing /bin/ls");
return EXIT_FAILURE;
}
I don't understand the std::vector<std::string *> part (are you sure you don't need a std::vector<std::string>?), anyway...
Rule for const: it's applied to the element on the left; if there is non element on the left, it's applied to the element on the right.
So a const char** (or char const **, if you prefer) is a pointer to a pointer to a constant char. I mean: the constant part is the char pointed, not the pointers.
And char * const * is a pointer to a constant pointer to a char; in this case the constant part is one of the two pointers, not the char pointed.
In your case the function
execvp(const char* file, char* const argv[])
expect, as second parameter, a char * const argv[] (a C-style array of constant pointers to a char) that you can see as a char * const *.
But you call
execvp(args[0], argv);
where argv is a char const **, that is different to a char * const *.
So the error: the function expect to be able to modify the pointed char's and you pass a pointer to a pointer to not modifiable char's
And you can't define argv as a char * const *
char * cont * argv = new char * const [numArgs]; // <-- WRONG
because you can't modify it.
So, to solve the problem, I suppose you can define argv as a char **
char** argv = new char* [numArgs];
for(size_t j = 0; j < numArgs; ++j)
argv[j] = args[j];
execvp(args[0], argv);
There ins't problem if you pass a not-constant object to a function that require a constant one (the contrary can be a problem), so you can pass a char ** to a function that expect a char * const *.
1) You don't need to have const * (const pointer) because pointer is automatically converted to const pointer if needed;
2) But you do need to supply char* (not const char* !) array as a second argument of execvp, i.e. your string characters should be modifiable. By having such a signature, execvp reserve its right to modify the supplied argument strings (yes it seems strange - but a process does have right to change its argument - note that main() routine may have (non-const) char** argv arguments!). Thus, you need to get rid of const char* in your piece of code and replace them by char *
The standard C library functions strtof and strtod have the following signatures:
float strtof(const char *str, char **endptr);
double strtod(const char *str, char **endptr);
They each decompose the input string, str, into three parts:
An initial, possibly-empty, sequence of whitespace
A "subject sequence" of characters that represent a floating-point value
A "trailing sequence" of characters that are unrecognized (and which do not affect the conversion).
If endptr is not NULL, then *endptr is set to a pointer to the character immediately following the last character that was part of the conversion (in other words, the start of the trailing sequence).
I am wondering: why is endptr, then, a pointer to a non-const char pointer? Isn't *endptr a pointer into a const char string (the input string str)?
The reason is simply usability. char * can automatically convert to const char *, but char ** cannot automatically convert to const char **, and the actual type of the pointer (whose address gets passed) used by the calling function is much more likely to be char * than const char *. The reason this automatic conversion is not possible is that there is a non-obvious way it can be used to remove the const qualification through several steps, where each step looks perfectly valid and correct in and of itself. Steve Jessop has provided an example in the comments:
if you could automatically convert char** to const char**, then you could do
char *p;
char **pp = &p;
const char** cp = pp;
*cp = (const char*) "hello";
*p = 'j';.
For const-safety, one of those lines must be illegal, and since the others are all perfectly normal operations, it has to be cp = pp;
A much better approach would have been to define these functions to take void * in place of char **. Both char ** and const char ** can automatically convert to void *. (The stricken text was actually a very bad idea; not only does it prevent any type checking, but C actually forbids objects of type char * and const char * to alias.) Alternatively, these functions could have taken a ptrdiff_t * or size_t * argument in which to store the offset of the end, rather than a pointer to it. This is often more useful anyway.
If you like the latter approach, feel free to write such a wrapper around the standard library functions and call your wrapper, so as to keep the rest of your code const-clean and cast-free.
Usability. The str argument is marked as const because the input argument will not be modified. If endptr were const, then that would instruct the caller that he should not change data referenced from endptr on output, but often the caller wants to do just that. For example, I may want to null-terminate a string after getting the float out of it:
float StrToFAndTerminate(char *Text) {
float Num;
Num = strtof(Text, &Text);
*Text = '\0';
return Num;
}
Perfectly reasonable thing to want to do, in some circumstances. Doesn't work if endptr is of type const char **.
Ideally, endptr should be of const-ness matching the actual input const-ness of str, but C provides no way of indicating this through its syntax. (Anders Hejlsberg talks about this when describing why const was left out of C#.)
I have a class with a method with the following signature:
void print(unsigned char *word);
I need to set "" as default value for word, how can I do that?
I tried the obvious void print(unsigned char *word=""); but I got the following error:
error: cannot initialize a parameter of type
'unsigned char *' with an lvalue of type 'const char [1]'
void print(unsigned char *word="");
Since I can't initialize word with a string literal who should I do it?
You say that this is a "prefix" argument to apply to the printing.
The answer is that you should make the argument const, stop doing whatever mutations you're doing to it inside the function, and then use "" as a default argument:
void print(const char* prefix = "")
try
unsigned char empty[] = { 0 };
void print(unsigned char* word = empty )
{
...
}
"" yields an array of const char, whereupon you want an array of or pointer to NON-const unsigned char, both the type and the cv-qualification don't fit.
Note also that in C++ char != signed char and char != unsigned char.
Possibly you mean void print(const char *word);, but probably you want just print(std::string const &) or print(std::string).
void print();
void print(unsigned char* prefix);
// in cpp file:
void print(){
unsigned char temp = 0;
print(&temp);
}
This provides two overloads, one with 0 and one eith one argument.
The zero argument one has some automatic storage memory it provides to the one argument one. Note that only the single byte under the pointer is valid to read/write: without a length, print has no way to know any different anyhow.
While there is no array, none is needed for a single element.