Convert auto (string) to char in D - d

For iterate with foreach loop and get dates over the files I need to have as input char [], but not string.
I wrote next code:
auto files = dirEntries ("E:\\ddd", SpanMode.shallow);
foreach (file; files)
{
char [] s = to!char[](file); //it's crap... and do not work...
writeln(file);
}
I use next method http://dlang.org/phobos/std_file.html#.getTimes
it's need as input char []: (in char[] name)

To get a mutable copy of immutable array you may use .dup:
char[] s = file.dup;
However in your case you don't need to do any conversion. getTimes accepts in char[] which is shortcut for scope const char[]. It it perfectly legal to pass immutable arrays as const arguments so it should "just work".

Your conversion line should look like:
... = to!(char[])(file.name);
This is because the shorthand template instantiation isn't valid for multiple tokens.
Second, there should be no need to convert to char[], as you said getTimes takes an "in char[]" which means it will not modify the string which means the immutable(char)[] can be passed without conversion.

You can also use :
const char[] s = cast(char[]) file;

Related

Character Pointer and string variable

I tried to use a character Pointer go throw string character (iterate) but I found i can not say the below:
string Name = "Hello";
char *ch = Name;
like the previous statements i am getting error during execution.
However when I am doing like that:
char *ch = "Hello";
the program running without throwing any exception.
Why is that?
I have recently encountered similar problem and the simplest answer is that std::string is a different type from char*, more precisely std::string is an object which contains some characters (your text) and few methods, which allow you to do multiple operations with your text. You can imagine creating a class Integer for storing the value, but also a method allowing you to square and cube the number which is stored in the Ingerer class. Even though they could store the same numerical value, you will not be able to compare them (unless you overload the operator==), as their types are different.
If you wish to use the code you provided, you need to rewrite the second line as
const char *ch = Name.c_str();
it is allowed because std::string contains a method c_str() which "casts" itself to const char*. If you want to learn more about strings, be sure to visit C++ reference about strings.

C++ environmental variable

What I am trying to do is to get environmental variable value and use it in code itself.
What I am trying to do is (with variable set as export UTMZONE="33T"):
char UTMZone[4] = getenv("UTMZONE");
With that I receive following error:
error: array must be initialized with a brace-enclosed initializer
I presume issue is with mixing types, but I have no idea what kind of conversion do I have to make.
getenv returns a char*. There isn't a way to initialize a char[N] from a char*. What you would need to do is capture the pointer and then copy the string to the array like
char UTMZone[4];
char* ret = getenv("UTMZONE");
if (ret)
strncpy(UTMZone, ret, 4);
else
// abort
That said, if you can use a std::string, that is constructable from a char*. Using
char* ret = getenv("UTMZONE");
if (ret)
std::string UTMZone = ret;
else
// abort
gives you a string populated with the environment variable. If you need to pass it to a something that needs a char* or const char* then you can use the data() or c_str() member functions respectively. That would look like
function_that_needs_char_star(UTMZone.data());
function_that_needs_const_char_star(UTMZone.c_str());
If you really want to use a char array and know for sure that you only need the first three chars of UTMZONE you could use this:
char* envptr = std::getenv("UTMZONE");
if(envptr){ // check the pointer isn't null
char UTMZone[4];
// set null terminator
UTMZone[4] = '\0';
// copy 3 chars as the null terminator is already there
std::strncpy(UTMZone, 3, envptr);
}
you should really use strings instead of char[] though as those are much safer.
edit: Nathan was both quicker and more eloquent :(
edit: adjusted for use of strncpy instead of strcpy and added NULL check

C++ change value in const char

I have a const char
const char example[] = "\x4D\x5A\xE8\x00\x00\x00\x00\x5B\x52\x45\x55\x89\xE5\x81\xC3";
and
DWORD* example2 = "\xAA\xBB\xCC\xDD";
and i want to change the last 4 bytes of example1 with those on example2
what can I do in C++?
i have tried memcpy , strcpy and strcpy_s with no luck
You should not modify a constant array!
Modifying a inherently constant object/variable leads to Undefined Behavior.
Just don't do it. Make a copy of it and modify that copy or if you want to modify the same array simply don't declare it as const.
Donot modify a constant string.
const char example[] = "\x4D\x5A\xE8\x00\x00\x00\x00\x5B\x52\x45\x55\x89\xE5\x81\xC3"; here, your string has a few NULL string terminator. This will NOT work with functions in <string.h> (such as strlen() and others)
Instead use memcpy, memset functions to append ONLY after knowing the length of the binary string.
Store your result in a character array, but don't assume it will work as a regular string because of your data.
your example[] char array is defined as const so you can not modify it.
1) You should get an eror in the compilation if you change your const char array in this way
example[2] ='R';
2) You should get a warning if you modify your const char array via memcpy or via strcpy
Change it to
char example[] = "\x4D\x5A\xE8\x00\x00\x00\x00\x5B\x52\x45\x55\x89\xE5\x81\xC3";
And you can not use strcpy because your character array contains x00 in the middle so this will affect the strcpy function. Because strcpy stop when it find x00 in the char array
example[] char array contains x00 in the middle, so to find the length of example[] with strlen will not work properly. For this case I suggest to use sizeof(example) instead.
Here after how you can make your copy:
char example[] = "\x4D\x5A\xE8\x00\x00\x00\x00\x5B\x52\x45\x55\x89\xE5\x81\xC3";
DWORD* example2 = "\xAA\xBB\xCC\xDD";
if (sizeof(example)>=sizeof(example2))
memcpy(example+sizeof(example)-sizeof(example2), example2, sizeof(example2));
Const variables can't be changed. This is by design. In the case of a c string, you can have the contents of the string const or the pointer to the string const.
Since you are defining it as a const character array, the pointer is implicitely const and the contents are explicitly const.
const char * const mystring = "hello"
In this case the first "const" tries to apply left (there is nothing), so it applies right (to the char type). So the string content may not change. The second const tries to apply left, so it makes the pointer itself const. That means that the mystring pointer must always point to where the "h" from "hello" in memory is.
So afterwards if I try:
mystring[0] = "y"
or
mystring = "gooodbye!"
They would not work. If you removed the first or second const respectively, they could be made to work.
The purpose of const allows you to say ahead of time "this variable cannot be modified". That means that if it is modified then there is a problem. Generally you should always use const with any variable that you do not want to be modified after instantiation.
You should never modify a constant including a constant array. If you want to change what you have above, create a copy of it and change the copy. As pointed out by RasmusKaj strcpy will not help you here as the source strings contains zero chars so maybe use memcpy for the creation of the copy.

Assign list element to a char*

I've appends some elements in my list
std::list<std::string> dirList2;
//Code
dirList2.push_back(findData.cFileName);
copy(dirList2.begin(), dirList2.end(),std::ostream_iterator<std::string> (std::cout,"\n"));
Everything work, i can view this items,
Now i want to assign the first elem of my list to a char* .
Can someone help me please ? i'dont know how to do it
If I understood well what you want then you can do it like this:
const char *s = dirList2.front().c_str();
Be careful, though. The C string which variable s points to is owned by the string object sitting on your list. If the list goes out of scope or you remove the element from your list, then the C string will be released by the std::string's destructor and your s pointer will not be valid.
If you want to manipulate the C string beyond the liftime of the std::string object than you can do sth. like this:
const char *s = strdup(dirList2.front().c_str());
But it's usually better to use std::string instead of raw C pointers, unless you have no choice.
The string object provides a c_str() method which will return a const char *. If you need to modify the string you must also make a copy of the string (IE using strcpy where the source pointer is the one returned by c_str())

Convert std::string to char * alternative

I have done a search in google and been told this is impossible as I can only get a static char * from a string, so I am looking for an alternative.
Here is the situation:
I have a .txt file that contains a list of other .txt files and some numbers, this is done so the program can be added to without recompilation. I use an ifstream to read the filenames into a string.
The function that they are required for is expecting a char * not a string and apparently this conversion is impossible.
I have access to this function but it calls another function with the char * so I think im stuck using a char *.
Does anyone know of a work around or another way of doing this?
In C++, I’d always do the following if a non-const char* is needed:
std::vector<char> buffer(str.length() + 1, '\0');
std::copy(str.begin(), str.end(), buffer.begin());
char* cstr = &buffer[0];
The first line creates a modifiable copy of our string that is guaranteed to reside in a contiguous memory block. The second line gets a pointer to the beginning of this buffer. Notice that the vector is one element bigger than the string to accomodate a null termination.
You can get a const char* to the string using c_str:
std::string str = "foo bar" ;
const char *ptr = str.c_str() ;
If you need just a char* you have to make a copy, e.g. doing:
char *cpy = new char[str.size()+1] ;
strcpy(cpy, str.c_str());
As previous posters have mentioned if the called function does in fact modify the string then you will need to copy it. However for future reference if you are simply dealing with an old c-style function that takes a char* but doesn't actually modfiy the argument, you can const-cast the result of the c_str() call.
void oldFn(char *c) { // doesn't modify c }
std::string tStr("asdf");
oldFn(const_cast< char* >(tStr.c_str());
There is c_str(); if you need a C compatible version of a std::string. See http://www.cppreference.com/wiki/string/basic_string/c_str
It's not static though but const. If your other function requires char* (without const) you can either cast away the constness (WARNING! Make sure the function doesn't modify the string) or create a local copy as codebolt suggested. Don't forget to delete the copy afterwards!
Can't you just pass the string as such to your function that takes a char*:
func(&string[0]);