使用boost :: filesystem,如何防止覆盖以前的密码文件?

如何解决使用boost :: filesystem,如何防止覆盖以前的密码文件?

好的,我对C ++和编码一般还是陌生的。我正在使用一个密码生成器,该密码生成器随机生成一个介于33和126之间的数字,然后使用相应的ASCII码并创建用户指定长度的密码。然后,我想使用boost :: filesystem创建一个密码文件夹,并在该文件夹中使用std :: ofstream创建一个包含密码的文本文件。我已经弄清楚了如何创建文件夹以及如何创建文件。但是...我需要一种方法来确定文件夹中是否已经有密码文件,如果有,请按数字顺序创建名称不同的密码文件(因为写入文件会覆盖以前的密码)。例如,如果我要运行该程序3次,则passwords文件夹中将包含三个文件,分别名为“ password.txt”,“ password2.txt”和“ password3.txt”。这是我到目前为止的内容:

namespace fs = boost::filesystem;

void savePassword(char array[],fs::path dir)
{
    std::cout << "Saving...\n";
    //this is where there needs to be a check,and the check needs to return how many password files there are
    std::ofstream savePw;
    savePw.open("./Passwords/password.txt"); //check to see if file exists before this,if so,make it "./Passwords/password" += number of files += ".txt"
    if (!savePw) {
        std::cout << "ERROR: File could not be opened.\n";
    }
    else {
        savePw << "Your password is:\n" << static_cast<std::string>(array) << '\n';
        savePw.close();
        std::cout << "Saved to: " << dir << '\n' << "Thanks for using the SPG!\n";
    }
}

fs::path createFolder() //creates folder and returns the directory to be passed to savePassword()
{
    fs::path dir{ boost::dll::program_location().parent_path() += "\\Passwords" };
    fs::create_directory(dir);
    return dir;
}

做了很多研究,但还没有真正发现任何东西。我已经尝试了boost :: filesystem :: directory_iterator,但是并不太了解如何使用它。我也尝试过将路径转换为字符串并使用std :: stoi,但这是失败的。任何帮助深表感谢。 :)

解决方法

Boost.Filesystem提供了名为exists的操作,以及用于查询文件status的其他操作。您可以使用如下所示的循环生成文件名:

fs::path generate_filename(fs::path const& dir)
{
    fs::path path = dir / "password.txt";
    unsigned int counter = 1u;
    while (true)
    {
        if (!fs::exists(path))
            break;

        ++counter;
        if (counter == 0u)
            throw std::runtime_error("Failed to generate a unique file name");

        path = dir / std::string("password")
            .append(std::to_string(counter)).append(".txt");
    }

    return path;
}

但是,请注意该代码是合理的,因为可以在调用exists和打开文件进行写入之间创建文件。解决方案是在打开文件时测试文件是否存在。

从C ++ 20开始,标准C ++文件流不允许在打开文件进行写入时测试文件是否存在,因此您将不得不使用其他文件API。以{11}开头的C {11}允许在文件打开模式下指定“ x”,以表明该功能必须在文件存在的情况下失败。您必须查阅编译器或标准C库文档,以查看其是否支持此新增功能。

或者,您可以使用低级文件系统API,例如在POSIX系统上使用O_CREATO_EXCL标志进行fopen调用,或使用带有CREATE_NEW标志的open在Windows上。


一些不相关的笔记。

  1. 您不需要static_cast<std::string>(array)即可将C样式的字符串输出到流中。直接输出字符数组将起作用-数组中的字符将被写入流,直到第一个空字符(终止符)为止。通过强制转换,您不必分配动态内存并在输出之前复制字符串。

  2. 除非函数体要求,否则请避免按值在函数参数中接受可能较大的对象,例如容器,字符串或路径。您最好将fs::path dir参数作为const引用(fs::path const& dir)接受,这样可以避免在调用savePassword时必须复制路径。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-