用c++编写批处理文件并执行,之后应删除批处理脚本[已关闭]

lndjwyie  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(122)

**已关闭。**此问题为not reproducible or was caused by typos。当前不接受答案。

这个问题是由打字错误或无法再重现的问题引起的。虽然类似的问题在这里可能是on-topic,但这个问题的解决方式不太可能帮助未来的读者。
2天前关闭。
Improve this question
我是编程新手,我正在尝试做一个小应用程序,可以删除文件夹DownloadsDocumentsPictures和桌面中的文档。
现在,我有4个脚本,但我只想拥有必须运行的.exe应用程序。
这就是为什么我希望我的C++应用程序编写我之前定义的脚本,执行它,然后删除它。
我有一个方法,可以用在你好世界上,但是不知怎么的,它不适合我的剧本。
此代码的错误代码:

void cleardown() {
    cout <<"Starting Batch File...\n";
    ofstream batch;
    batch.open("down.bat", ios::out);
    batch << "@echo off\n";
    batch <<"SETLOCAL";
    batch <<"SET \"sourcedir3=C:\Users\%username%\Downloads\"\n" ;
    batch <<"SET \"keepfile=POOL.bat\"\n";
    batch <<"FOR %%a IN (\"%sourcedir3%\* \") DO IF /i NOT \"%%~nxa"=="%keepfile%\" DEL \"%%a\"\n";
    batch <<"GOTO :EOF\n";
    batch.close();
    
    system("down.bat  & del down.bat");
    cout <<"Done!" << endl;
    delay();
    system ("cls");
}
|81|error: no match for 'operator==' (operand types are 'std::basic_ostream<char>' and 'const char [23]')|

第81行是这一行:

batch <<"FOR %%a IN (\"%sourcedir3%\* \") DO IF /i NOT \"%%~nxa"=="%keepfile%\" DEL \"%%a\"\n";

下面是列出的函数之一的代码:

void cleardown() {
    cout <<"Starting Batch File...\n";
    ofstream batch;
    batch.open("down.bat", ios::out);
    batch << "@echo off\n";
    batch <<"SETLOCAL";
    batch <<"SET "sourcedir3=C:\Users\%username%\Downloads"\n" ;
    batch <<"SET "keepfile=POOL.bat"\n";
    batch <<"FOR %%a IN ("%sourcedir3%\*") DO IF /i NOT "%%~nxa"=="%keepfile%" DEL "%%a"\n";
    batch <<"GOTO :EOF\n";
    batch.close();

    system("down.bat  & del down.bat");
    cout <<"Done!" << endl;
    delay();
    system ("cls");
}
vmdwslir

vmdwslir1#

这是我的最终结果,结束了工作thx为您的帮助@ π ντα ε

void cleardown() {
    cout <<"Starting Batch File...\n";
    ofstream batch;
    batch.open("down.bat", ios::out);
    batch << "@echo off\n";
    batch <<"SETLOCAL;\n";
    batch <<"SET \"sourcedir3=C:\\Users\\%username%\\Downloads\"\n";
    batch <<"SET \"keepfile=POOL.bat\"\n";
    batch <<"FOR %%a IN (\"%sourcedir3%\\*\") DO IF /i NOT \"%%~nxa\"==\"%keepfile%\" DEL \"%%a\"\n";
    batch <<"GOTO :EOF\n";
    batch.close();

    system("down.bat  & del down.bat");
    cout <<"Done!" << endl;
    delay();
    system ("cls");
}
jtjikinw

jtjikinw2#

发生编译器错误的原因是您没有转义字符串文字中==周围的2个"字符:

batch <<"FOR %%a IN (\"%sourcedir3%\* \") DO IF /i NOT \"%%~nxa"=="%keepfile%\" DEL \"%%a\"\n";
                                                               ^  ^

因此,最后只执行以下部分:

batch <<"FOR %%a IN (\"%sourcedir3%\* \") DO IF /i NOT \"%%~nxa"

其中<<返回一个ostream&batch的引用,然后尝试使用==运算符将该引用与字符串文本"%keepfile%\" DEL \"%%a\"\n"进行比较。由于ostream没有定义这样的比较,因此编译器出错。
您需要转义这2个"字符,例如:

batch <<"FOR %%a IN (\"%sourcedir3%\* \") DO IF /i NOT \"%%~nxa\"==\"%keepfile%\" DEL \"%%a\"\n";
                                                                ^   ^

还有一个\字符也需要转义:

batch <<"FOR %%a IN (\"%sourcedir3%\* \") DO IF /i NOT \"%%~nxa\"==\"%keepfile%\" DEL \"%%a\"\n";
                                   ^

以及其他字符串常量中的几个\字符:

batch <<"SET \"sourcedir3=C:\Users\%username%\Downloads\"\n" ;
                            ^     ^          ^

也就是说,在C++11和更高版本中,您应该考虑使用raw string literal,这样您就完全不需要担心转义字符,例如:

void cleardown() {
    cout << "Starting Batch File...\n";
    ofstream batch("down.bat");
    batch << "@echo off" << '\n';
    batch << "SETLOCAL;" << '\n';
    batch << R"(SET "sourcedir3=C:\Users\%username%\Downloads")" << '\n';
    batch << R"(SET "keepfile=POOL.bat")" << '\n';
    batch << R"(FOR %%a IN ("%sourcedir3%\*") DO IF /i NOT "%%~nxa"=="%keepfile%" DEL "%%a")" << '\n';
    batch << "GOTO :EOF" << '\n';
    batch.close();

    system("down.bat  & del down.bat");
    cout << "Done!" << endl;
    delay();
    system("cls");
}

或者:

void cleardown() {
    cout << "Starting Batch File...\n";
    ofstream batch("down.bat");
    batch << R"(
@echo off
SETLOCAL;
SET "sourcedir3=C:\Users\%username%\Downloads"
SET "keepfile=POOL.bat"
FOR %%a IN ("%sourcedir3%\*") DO IF /i NOT "%%~nxa"=="%keepfile%" DEL "%%a"
GOTO :EOF
)";
    batch.close();

    system("down.bat  & del down.bat");
    cout << "Done!" << endl;
    delay();
    system("cls");
}

首先,在这种情况下,您根本没有理由写出并执行一个.bat文件,您可以并且应该直接从您自己的代码中删除这些文件(从而满足您的“我只想拥有.exe应用程序”的需求),例如:

#include <iostream>
#include <filesystem>
#include <string>
#include <memory>
#include <stdexcept>

#include <windows.h>
#include <shlobj.h>

using namespace std;
namespace fs = std::filesystem;

fs::path GetDownloadsPath() {
    // Ask the OS where the folder is actually located, do not hard-code it!
    // It is NOT located at C:\Users\%username%\Downloads on everyone's machine,
    // but the OS always knows where it actually is...
    PWSTR pszPath = nullptr;
    if (FAILED(SHGetKnownFolderPath(FOLDERID_Downloads, 0, nullptr, &pszPath)))
        throw std::runtime_error("Can't get path to Downloads folder");
    std::unique_ptr<WCHAR, decltype(&CoTaskMemFree)> deleter(pszPath, &CoTaskMemFree);
    return fs::path(pszPath);
}

int CompareInsensitive(const wstring &str1, const wstring &str2) {
    return CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, str1.c_str(), str1.size(), str2.c_str(), str2.size()) - 2;
    // alternatively:
    // return CompareStringOrdinal(str1.c_str(), str1.size(), str2.c_str(), str2.size(), TRUE) - 2;
}

void cleardown() {
    cout << "Deleting Files...\n";

    const fs::path sourcedir = GetDownloadsPath();
    const wstring keepfile = L"POOL.bat";

    for (const auto &dir_entry : fs::directory_iterator(sourcedir))
    {
        const fs::path dir_path = dir_entry.path();
        if (CompareInsensitive(dir_path.filename(), keepfile) != 0) {
            fs::remove(dir_path);
        }
    }

    cout << "Done!" << endl;
    delay();
    system("cls");
}

相关问题