3

I am trying to copy a folder by SHFileOperationA function. Here is my code.

int main()  {

    SHFILEOPSTRUCTA sf;
    int result;

    string source = "D:\\check\\folder4";
    string dest = "D:\\Documents\\test\\folder4";

    sf.pFrom = source.c_str( );
    sf.pTo = dest.c_str( );
    sf.wFunc = FO_COPY;
    sf.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SILENT;

    result = SHFileOperationA(&sf);

    return 0;
}

I am not able to understand that how to make the string appended by \0 twice. I tried something like this.

    string source = "D:\\check\\folder4\\0\\0";
    string dest = "D:\\Documents\\test\\folder4\\0\\0";

But, it is not working. I have also tried few more combinations but none of them is working. Please can anyone suggest me how to solve this?

I can solve the problem by directly assigning the paths like this:-

    sf.pFrom = "D:\\check\\folder4";
    sf.pTo = "D:\\Documents\\test\\folder4";

and the problem gets solved but my intention is to make use of strings. Please can anybody help me with this.

Also, if possible can anybody tell me why directly assigning the string constant i.e sf.pFrom = "D:\\check\\folder4"; is working and assigning using a string like sf.pFrom = source.c_str( ); is not working?

Thanks in advance.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Prasad
  • 5,946
  • 3
  • 30
  • 36

1 Answers1

2

The std::string does strlen (or similar) to find the end of the constant char array and allocates only the required number of characters. So it stops on the first null and does not copy the other one. If you want to override this, you need to use constructor that takes size, like:

string source("D:\\check\\folder4\\0", 18);

Note that the second null character is added automatically just as with any other string.

Or add the null character explicitly like (way better solution):

std::string source = std::string("D:\\check\\folder4") + std::string(1, '\0');

Or

std::string source = "D:\\check\\folder4";
source.append(1, '\0');

As for the other question, why using constant character array works:

I believe that, if it works, it just a pure luck that the byte/character in memory after the constant character array is null.

You can test this yourself (in debugger or by printing the values):

// this is the compiler generated null
(*(sf.pFrom + strlen(sf.pFrom))) == '\0'

// this is the following byte/character that should be luckily null
(*(sf.pFrom + strlen(sf.pFrom) + 1)) == '\0' 

If you find that the following character is not null in debugger, make sure you finish debugging until the SHFileOperationA. As in that particular case it can fail/crash/whatever (while it normally does not) as the fact you are debugging alone may make the memory image different.

Also you have not specified what you exactly mean by "it works". Do you mean result of SHFileOperationA (what is it). Or that the application crashes/throws, when it does not work. Or that the files are copied or not. This might help answering you.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Hi @Martin. Thanks for the reply. It is working now. But the second part is not clear to me. I am not explicitly adding `\0` so there will be only one `'\0'` character added by compiler. Or you mean to say in buffer, possibly the next character after compiler created one `'\0'` is also luckily happened to be `'\0'` which is why it worked? – Prasad Apr 12 '13 at 12:16
  • Well, yes it's possible that you were just lucky :) Please accept the answer, if it helped you. – Martin Prikryl Apr 12 '13 at 12:24
  • But I am not satisfied actually. Though it might be coincidentally an additional `\0` character was there, what else can be the possibilities for me to get the correct answer with character arrays. Yes, your answer has helped me, and I will accept your answer but please list out the other possibilities for me. – Prasad Apr 12 '13 at 13:17
  • Thanks. I have updated the answer. If it does not help, please update your question to specify what does it mean "it works/doesn't work". – Martin Prikryl Apr 12 '13 at 13:31
  • 1
    Sorry for the late reply. Yeah, luckily it is happening to be NULL character. That's why it was working. By working I meant that folder was getting copied. Thanks for all your help and patience. :) – Prasad Apr 15 '13 at 04:21