How to Copying a folder in VC++? - visual-c++

How to copy a folder from one drive to other drive in VC++ ...?
I have come this far
String^ SourcePath = Directory::GetCurrentDirectory();
String^ DestinationPath = "c:\\Test";
CString s(SourcePath) ;
CString d(DestinationPath);
Directory::CreateDirectory(DestinationPath);
SHFILEOPSTRUCT* pFileStruct = new SHFILEOPSTRUCT;
ZeroMemory(pFileStruct, sizeof(SHFILEOPSTRUCT));
pFileStruct->hwnd = NULL;
pFileStruct->wFunc = FO_COPY;
pFileStruct->pFrom = (LPCWSTR)s;//"D:\test_documents\test1.doc";
pFileStruct->pTo = (LPCWSTR)d;
pFileStruct->fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR ;
bool i = pFileStruct->fAnyOperationsAborted ;
int status = SHFileOperation(pFileStruct);
if(status == 0)
{
return true;
}
return false;
the status is showing 2 instead of zero , can some one tell me why..?

Usually a String^ points to a managed string object. The SHFILOPSSTRUCT must befilled with pointers to unmanaged wchar_t. So you must pin the strings and convert. You tried to use the CString class as conversion helper.
Use the PtrToStringChars instead to get valid strings in pTo and pFrom:
http://msdn.microsoft.com/en-us/library/d1ae6tz5(VS.80).aspx
The read of the fAnyOperationsAborted member is not required for the operation.

Related

Grabbing first number in string after some keyword occurrence in C++ (Arduino)

I have a string coming from PC through serial to a microcontroller (Arduino), e.g.:
"HDD: 55 - CPU: 12.6 - Weather: Cloudy [...] $";
by this function I found:
String inputStringPC = "";
boolean stringCompletePC = false;
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputStringPC += inChar;
if (inChar == '$') // end marker of the string
{
stringCompletePC = true;
}
}
}
I would like to extract the first number of it after the word HDD, CPU and also get the string after Weather (ie "cloudy"); my thinking is something like that:
int HDD = <function that does that>(Keyword HDD);
double CPU = <function that does that>(Keyword CPU);
char Weather[] = <function that does that>(Keyword Weather);
What is the right function to do that?
I looked into inputStringSerial.indexOf("HDD") but I am still a learner to properly understand what it does and don't know if theres a better function.
My approach yielded some syntax errors and confused me with the difference in usage between "String inputStringSerial" (class?) and "char inputStringSerial[]" (variable?). When I do 'string inputStringSerial = "";' PlatformIO complains that "string" is undefined. Any help to understand its usage here is greatly appreciated.
Thanks a bunch.
The String class provides member functions to search and copy the contents of the String. That class and all its member functions are documented in the Arduino Reference:
https://www.arduino.cc/reference/tr/language/variables/data-types/stringobject/
The other way a list of characters can be represented is a char array, confusingly also called a string or cstring. The functions to search and copy the contents of a char array are documented at
http://www.cplusplus.com/reference/cstring/
Here is a simple Sketch that copies and prints the value of the Weather field using a String object. Use this same pattern - with different head and terminator values - to copy the string values of the other fields.
Once you have the string values of HDD and CPU, you'll need to call functions to convert those string values into int and float values. See the String member functions toInt() and toFloat() at
https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/toint/
or the char array functions atoi() and atof() at
http://www.cplusplus.com/reference/cstdlib/atoi/?kw=atoi
String inputStringPC = "HDD: 55 - CPU: 12.6 - Weather: Cloudy [...] $";
const char headWeather[] = "Weather: "; // the prefix of the weather value
const char dashTerminator[] = " -"; // one possible suffix of a value
const char dollarTerminator[] = " $"; // the other possible suffix of a value
void setup() {
int firstIndex; // index into inputStringPC of the first char of the value
int lastIndex; // index just past the last character of the value
Serial.begin(9600);
// find the Weather field and copy its string value.
// Use similar code to copy the values of the other fields.
// NOTE: This code contains no error checking for unexpected input values.
firstIndex = inputStringPC.indexOf(headWeather);
firstIndex += strlen(headWeather); // firstIndex is now the index of the char just past the head.
lastIndex = inputStringPC.indexOf(dollarTerminator, firstIndex);
String value = inputStringPC.substring(firstIndex, lastIndex);
Serial.print("Weather value = '");
Serial.print(value);
Serial.println("'");
}
void loop() {
// put your main code here, to run repeatedly:
}
When run on an Arduio Uno, this Sketch produces:
Weather value = 'Cloudy [...]'

Error in using indexOf not finding char in Arduino String

I have some code that I have no clue why it isn't working.
The code takes a serial input in the form of "xxx,yyy,zzz", where digits can range from 1 to 3 in each number. Because of an odd quirk in an app, it needs to be read as a char, then converted to a string to be handled. The intention is to split into 3 ints, red green and blue, from "RRR,GGG,BBB".
Now this works fine when I manually define String str (see commented code), but when I go and enter it from the serial console, it doesn't want to work. It seems to be coming from the indexOf(',') part, as while using Serial.print(c1);, I found that when I manually entered a string, it returned an index of the comma, but when I used the serial console, it returned -1 (not found).
And yes, the entered string into the console is in the correct format of "RRR,GGG,BBB", I've confirmed that by printing both phone and str independently.
while (Serial.available() > 0) {
char phone = Serial.read();
String str = String(phone);
//String str = "87,189,183";
int ln = str.length()-1;
int c1 = str.indexOf(','); //first place to cut string
int c2 = str.indexOf(',',c1+1); //second place
red = str.substring(0,c1).toInt();
green = str.substring(c1,c2).toInt();
blue = str.substring(c2,ln).toInt();
Serial.print(red);
Edit: With the Arduino String class, creating a string from a char is returning more than just one character, eleven in fact.
This:
char phone = Serial.read();
String str = String(phone);
will never create a string in str that has more than 1 character, since that's what you say you want.
This is the code for the Arduino's String(char) constructor:
String::String(char c)
{
init();
char buf[2];
buf[0] = c;
buf[1] = 0;
*this = buf;
}
So clearly your code will create a 1-character long string.
Also, beware of using indexes computed on the full string, on substrings later.
I'm try to guess that you are using these serial API http://playground.arduino.cc/Interfacing/CPPWindows.
while (Serial.available() > 0) {
char buf[12];
int len = Serial.ReadData(buf,11);
String str = String(buf);
//String str = "87,189,183";
int ln = str.length()-1;
int c1 = str.indexOf(','); //first place to cut string
int c2 = str.indexOf(',',c1+1); //second place
red = str.substring(0,c1).toInt();
green = str.substring(c1,c2).toInt();
blue = str.substring(c2,ln).toInt();
Serial.print(red);
If you are using other API like http://arduino.cc/en/Serial/Read you should follow these API where Serial is a Stream and read() return just the first available char.
Code was fixed by using a different function.
while (Serial.available() > 0) {
char phone = Serial.read();
str += phone;
//String str = "87,189,183";
int ln = str.length()-1;
int c1 = str.indexOf(','); //first place to cut string
int c2 = str.indexOf(',',c1+1); //second place
red = str.substring(0,c1).toInt();
green = str.substring(c1,c2).toInt();
blue = str.substring(c2,ln).toInt();
Serial.print(red);
I'm not sure why this works, and why before I was getting a string with more than one character. But it works!

Convert string to double do not respect current number decimal separator

I'm trying to convert a string representing a double from invariant culture to a double in current culture representation, I'm concerned with how to get the new double representation to use the current number decimal separator of Current Culture.
I used the code below for the conversion :
public static double ConvertToDouble(this object inputVal, bool useCurrentCulture = false)
{
string currentSep = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
string invariantSep = CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator;
if (inputVal.GetType() == typeof(string))
{
if (!currentSep.Equals(invariantSep))
{
inputVal = (inputVal as string).Replace(invariantSep, currentSep);
}
}
if (useCurrentCulture)
return Convert.ToDouble(inputVal, CultureInfo.CurrentCulture);
else
return Convert.ToDouble(inputVal);
}
But the above code always gives me a double with ".", although I use the CurrentCulture for example French supposed to give me a double with comma (",").
Many thanks in advance for any hint.
FreeDev
But the above code always gives me a double with "." as the NumberDecimalSeparator
No, it returns a double. A double is just a number. It doesn't have a NumberDecimalSeparator... only a culture does, and that's only applied when converting to or from strings. Talking about the separator for a double is like talking about whether an int is in decimal or hex - there's no such concept. 0x10 and 16 are the same value, represented by the same bits.
It's not really clear what you're trying to do, but it's crucial to understand the difference between what's present in a textual representation, and what's inherent to the data value itself. You should care about the separator when parsing or formatting - but after you've parsed to a double, that information is gone.
From the comments and your question i guess that you actually want to convert a string to a double with either InvariantCulture or current-culture. This double should then be converted to a string which is formatted by the current-culture datetime-format informations(like NumberDecimalSeparator).
So this method should do two things:
parse string to double
convert double to string
public static string ConvertToFormattedDouble(this string inputVal, IFormatProvider sourceFormatProvider = null, IFormatProvider targetFormatProvider = null)
{
if (sourceFormatProvider == null) sourceFormatProvider = NumberFormatInfo.InvariantInfo;
if (targetFormatProvider == null) targetFormatProvider = NumberFormatInfo.CurrentInfo;
if (sourceFormatProvider == targetFormatProvider)
return inputVal; // or exception?
double d;
bool isConvertable = double.TryParse(inputVal, NumberStyles.Any, sourceFormatProvider, out d);
if (isConvertable)
return d.ToString(targetFormatProvider);
else
return null; // or whatever
}
You can use it in this way:
string input = "1234.567";
string output = input.ConvertToFormattedDouble(); // "1234,567"
Note that i've extended string instead of object. Extensions for object are a bad idea in my opinion. You pollute intellisense with a method that you 'll almost never use (although it applies also to string).
Update:
If you really want to go down this road and use an extension for object that supports any kind of numbers as (boxed) objects or strings you could try this extension:
public static string ConvertToFormattedDouble(this object inputVal, IFormatProvider sourceFormatProvider = null, IFormatProvider targetFormatProvider = null)
{
if (sourceFormatProvider == null) sourceFormatProvider = NumberFormatInfo.InvariantInfo;
if (targetFormatProvider == null) targetFormatProvider = NumberFormatInfo.CurrentInfo;
if (inputVal is string)
{
double d;
bool isConvertable = double.TryParse((string)inputVal, NumberStyles.Any, sourceFormatProvider, out d);
if (isConvertable)
return d.ToString(targetFormatProvider);
else
return null;
}
else if (IsNumber(inputVal))
{
decimal d = Convert.ToDecimal(inputVal, sourceFormatProvider);
return Decimal.ToDouble(d).ToString(targetFormatProvider);
}
else
return null;
}
public static bool IsNumber(this object value)
{
return value is sbyte
|| value is byte
|| value is short
|| value is ushort
|| value is int
|| value is uint
|| value is long
|| value is ulong
|| value is float
|| value is double
|| value is decimal;
}
Usage:
object input = 1234.56745765677656578d;
string output = input.ConvertToFormattedDouble(); // "1234,56745765678"

How do I use the IFileDialogCustomize::GetEditBoxText() method?

WCHAR wcText[100] = {0};
WCHAR *pText = wcText;
WCHAR **ppText = &pText;
HRESULT hr = pDialogCustomize->GetEditBoxText(dwCtrlID, ppText);
The edit box contains the text "5000" but this text isn't returned by the GetEditBoxText method.
How can I get the text from the edit box?
According to http://msdn.microsoft.com/en-us/library/bb775908%28VS.85%29.aspx, GetEditBoxText allocates and returns a string for you (that you must later free with CoTaskMemFree). I'm assuming that you're checking the wcText array after the function call, and it is empty? This is because GetEditBoxText is changing the value of pText.
Try:
WCHAR *pText = NULL;
HRESULT hr = pDialogCustomize->GetEditBoxText(dwCtrlID, &pText);
if (S_OK == hr && NULL != pText)
// function succeeded and pText points to a buffer of text that must free when done using

stick integer to string and char*

How can I add an integer variable to a string and char* variable? for example:
int a = 5;
string St1 = "Book", St2;
char *Ch1 = "Note", Ch2;
St2 = St1 + a --> Book5
Ch2 = Ch1 + a --> Note5
Thanks
The C++ way of doing this is:
std::stringstream temp;
temp << St1 << a;
std::string St2 = temp.str();
You can also do the same thing with Ch1:
std::stringstream temp;
temp << Ch1 << a;
char* Ch2 = new char[temp.str().length() + 1];
strcpy(Ch2, temp.str().c_str());
for char* you need to create another variable that is long enough for both, for instance. You can 'fix' the length of the output string to remove the chance of overrunning the end of the string. If you do that, be careful to make this large enough to hold the whole number, otherwise you might find that book+50 and book+502 both come out as book+50 (truncation).
Here's how to manually calculate the amount of memory required. This is most efficient but error-prone.
int a = 5;
char* ch1 = "Book";
int intVarSize = 11; // assumes 32-bit integer, in decimal, with possible leading -
int newStringLen = strlen(ch1) + intVarSize + 1; // 1 for the null terminator
char* ch2 = malloc(newStringLen);
if (ch2 == 0) { exit 1; }
snprintf(ch2, intVarSize, "%s%i", ch1, a);
ch2 now contains the combined text.
Alternatively, and slightly less tricky and also prettier (but less efficient) you can also do a 'trial run' of printf to get the required length:
int a = 5;
char* ch1 = "Book";
// do a trial run of snprintf with max length set to zero - this returns the number of bytes printed, but does not include the one byte null terminator (so add 1)
int newStringLen = 1 + snprintf(0, 0, "%s%i", ch1, a);
char* ch2 = malloc(newStringLen);
if (ch2 == 0) { exit 1; }
// do the actual printf with real parameters.
snprintf(ch2, newStringLen, "%s%i", ch1, a);
if your platform includes asprintf, then this is a lot easier, since asprintf automatically allocates the correct amount of memory for your new string.
int a = 5;
char* ch1 = "Book";
char* ch2;
asprintf(ch2, "%s%i", ch1, a);
ch2 now contains the combined text.
c++ is much less fiddly, but I'll leave that to others to describe.
You need to create another string large enough to hold the original string followed by the number (i.e. append the character corresponding to each digit of the number to this new string).
Try this out:
char *tmp = new char [ stelen(original) ];
itoa(integer,intString,10);
output = strcat(tmp,intString);
//use output string
delete [] tmp;

Resources