3

我正在尝试按SHFileOperationA功能复制文件夹。这是我的代码。

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;
}

我无法理解如何使字符串附加\0两次。我尝试过这样的事情。

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

但是,它不起作用。我还尝试了更多组合,但没有一个有效。请任何人都可以建议我如何解决这个问题?

我可以通过直接分配这样的路径来解决问题:-

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

问题得到解决,但我的意图是使用字符串。请任何人都可以帮我解决这个问题。

另外,如果可能的话,任何人都可以告诉我为什么直接分配字符串常量,即sf.pFrom = "D:\\check\\folder4";有效,而使用类似字符串的分配sf.pFrom = source.c_str( );无效?

提前致谢。

4

1 回答 1

2

dos (或类似的)查找常量 char 数组的末尾std::stringstrlen仅分配所需数量的字符。所以它在第一个 null 处停止并且不复制另一个。如果要覆盖它,则需要使用带大小的构造函数,例如:

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

请注意,与任何其他字符串一样,会自动添加第二个空字符。

或明确添加空字符(更好的解决方案):

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

或者

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

至于另一个问题,为什么使用常量字符数组有效:

我相信,如果它有效,那么常量字符数组之后内存中的字节/字符为空只是一种运气。

您可以自己测试(在调试器中或通过打印值):

// 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' 

如果您在调试器中发现以下字符不为空,请确保您完成调试,直到SHFileOperationA. 在那种特殊情况下,它可能会失败/崩溃/无论如何(虽然它通常不会),因为您单独调试的事实可能会使内存映像不同。

此外,您还没有具体说明“它有效”的确切含义。你的意思是SHFileOperationA(它是什么)的结果。或者应用程序崩溃/抛出,当它不起作用时。或者文件是否被复制。这可能有助于回答你。

于 2013-04-12T11:37:25.013 回答