3 votes

SHFileOperation copiant des dossiers à l'aide de chaînes de caractères

J'essaie de copier un dossier en SHFileOperationA fonction. Voici mon 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;
}

Je n'arrive pas à comprendre comment faire pour que la chaîne ajoutée par \0 deux fois. J'ai essayé quelque chose comme ça.

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

Mais, ça ne marche pas. J'ai également essayé quelques autres combinaisons mais aucune ne fonctionne. Quelqu'un peut-il me suggérer comment résoudre ce problème ?

Je peux résoudre le problème en assignant directement les chemins comme ceci :-

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

et le problème est résolu, mais mon intention est d'utiliser des chaînes de caractères. Quelqu'un peut-il m'aider à résoudre ce problème ?

En outre, si possible, quelqu'un peut-il me dire pourquoi l'affectation directe de la constante de la chaîne, c'est-à-dire sf.pFrom = "D:\\check\\folder4"; fonctionne et l'affectation en utilisant une chaîne comme sf.pFrom = source.c_str( ); ne fonctionne pas ?

Merci d'avance.

2voto

Martin Prikryl Points 4584

En std::string hace strlen (ou similaire) pour trouver la fin du tableau de caractères constants et n'alloue que le nombre de caractères requis. Ainsi, il s'arrête sur le premier null et ne copie pas l'autre. Si vous voulez outrepasser cela, vous devez utiliser un constructeur qui prend la taille, comme :

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

Notez que le deuxième caractère nul est ajouté automatiquement comme pour toute autre chaîne.

Ou ajouter le caractère nul explicitement comme (bien meilleure solution) :

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

Ou

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

Quant à l'autre question, pourquoi l'utilisation d'un tableau de caractères constants fonctionne-t-elle ?

Je pense que, si cela fonctionne, c'est juste une pure chance que l'octet/caractère en mémoire après le tableau de caractères constants soit nul.

Vous pouvez le tester vous-même (dans le débogueur ou en imprimant les valeurs) :

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

Si vous constatez que le caractère suivant n'est pas nul dans le débogueur, assurez-vous de terminer le débogage jusqu'à ce que l'option SHFileOperationA . Dans ce cas particulier, il peut échouer/se planter/quelque chose (alors qu'il ne le fait pas normalement) car le fait que vous déboguez seul peut rendre l'image mémoire différente.

Vous n'avez pas non plus précisé ce que vous entendez exactement par "ça marche". Voulez-vous dire le résultat de SHFileOperationA (qu'est-ce que c'est). Ou que l'application se bloque/se lance, lorsqu'elle ne fonctionne pas. Ou que les fichiers sont copiés ou non. Cela pourrait aider à vous répondre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X