2013-04-12 2 views
3

Я пытаюсь скопировать папку с помощью функции SHFileOperationA. Вот мой код.SHFileOperation копирование папок с использованием строк

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

и проблема становится решена, но мое намерение состоит в том, чтобы сделать использование строк. Пожалуйста, помогите мне с этим.

Кроме того, если возможно, кто-нибудь скажет мне, почему прямое назначение строковой константы i.e sf.pFrom = "D:\\check\\folder4"; работает и присваивается с помощью строки, такой как sf.pFrom = source.c_str(); не работает?

Заранее спасибо.

ответ

2

std::string делает strlen (или аналогичный), чтобы найти конец массива константных символов и выделяет только необходимое количество символов. Поэтому он останавливается на первом нуле и не копирует другой. Если вы хотите изменить это, вам нужно использовать конструктор, который принимает размер, как:

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'); 

Что касается другого вопроса, почему с использованием постоянного массива символов работает:

I верьте, что если это сработает, просто удача в том, что байт/символ в памяти после массива константных символов равен нулю.

Вы можете проверить это самостоятельно (в отладчик или напечатав значения):

// 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 (что это такое). Или что приложение вылетает/бросает, когда оно не работает. Или что файлы скопированы или нет. Это может помочь вам ответить.

+0

Hi @Martin. Спасибо за ответ. Он работает сейчас. Но вторая часть мне непонятна. Я явно не добавляю '\ 0', поэтому компилятор добавит только один символ' '\ 0''.Или вы хотите сказать в буфере, возможно, следующий символ после того, как компилятор создал один '' \ 0'', также, к счастью, оказался '' \ 0'', поэтому он сработал? – user1190882

+0

Ну, да, возможно, вам просто повезло :) Примите ответ, если это вам поможет. –

+0

Но я не удовлетворен на самом деле. Хотя это может быть случайным, появился еще один символ '\ 0', что еще может быть для меня возможностью получить правильный ответ с массивами символов. Да, ваш ответ помог мне, и я приму свой ответ, но, пожалуйста, перечислите другие возможности для меня. – user1190882