C++ 向量<;非单字符>;转换为字符串并返回

C++ 向量<;非单字符>;转换为字符串并返回,c++,sqlite,vector,C++,Sqlite,Vector,我正试图: 向量到字符串 将此字符串转换为常量字符* 将其插入到类型为VARCHAR(8192)的数据库列中,不进行文本或blob绑定 从数据库中读取它 将此字符串转换为向量 结果向量必须与1上插入的结果向量保持不变 最小可复制示例: vector<unsigned char> from = {'\200','a','\30'}; std::string result = from.to_string(); // Our function for converting to stri

我正试图:

  • 向量到字符串
  • 将此字符串转换为常量字符*
  • 将其插入到类型为
    VARCHAR(8192)
    的数据库列中,不进行文本或blob绑定
  • 从数据库中读取它
  • 将此字符串转换为向量
  • 结果向量必须与1上插入的结果向量保持不变

    最小可复制示例:

    vector<unsigned char> from = {'\200','a','\30'};
    std::string result = from.to_string(); // Our function for converting to string
    vector<unsigned char> to = vector<unsigned char>(result);
        //You need to have table "some_table" with column "value" for this to work
        //Insert result to database
        std::string sql =
            "INSERT INTO some_table ('value') VALUES ('"+result.c_str()+"')";
        int rc = sqlite3_exec(m_Db, sql, nullptr, nullptr, nullptr);
        // Select value from database
        rc += sqlite3_prepare_v2(m_Db,"SELECT value FROM some_table",
                                -1, &stmt, nullptr);
        if (rc != 101 && rc != 0) {
            LOG_F(INFO, "Failed to get the value");
        }
        sqlite3_step(stmt);
        vector<unsigned char> read_result = ConvertToVector(std::string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0))));
        sqlite3_finalize(stmt);
    //Read Result need to be same as from
    
    vector from={'\200','a','\30'};
    std::string result=from.to_string();//转换为字符串的函数
    向量到=向量(结果);
    //您需要有带有“value”列的“some_table”表才能工作
    //将结果插入数据库
    std::stringsql=
    “插入某些_表('value')值('“+result.c_str()+”)”;
    int rc=sqlite3_exec(m_Db,sql,nullptr,nullptr,nullptr);
    //从数据库中选择值
    rc+=sqlite3\u prepare\u v2(m\u Db,“从某些表中选择值”,
    -1、&stmt、nullptr);
    如果(rc!=101&&rc!=0){
    LOG_F(信息,“无法获取值”);
    }
    sqlite3_步骤(stmt);
    vector read_result=ConvertToVector(std::string(reinterpret_cast(sqlite3_column_text(stmt,0)));
    sqlite3_最终确定(stmt);
    //读取结果必须与从中读取的结果相同
    
    结果应与so中的向量相同:{'\25','a','\30'}

    我很高兴能找到一个有效、快速、通用的解决方案。 可能不要使用UTF-8等编码,因为这可能是一些用户数据库的问题


    如何正确执行此操作?

    构造函数和
    std::string
    std::vector
    都有一个重载,该重载使用定义新字符串或向量内容的序列的开始迭代器和结束迭代器。
    std::string
    std::vector
    都可以提供它们自己的开始迭代器和结束迭代器:

    std::vector<unsigned char> from = {'\200','a','\30'};
    std::string result{from.begin(), from.end()};
    std::vector<unsigned char> to{result.begin(), result.end()};
    
    std::vector from={'\200','a','\30'};
    字符串结果{from.begin(),from.end()};
    std::指向{result.begin(),result.end()}的向量;
    
    正确的方法是使用base64编码和解码

    它通常使用,无需blob_绑定即可工作


    撤消此操作将导致性能损失。

    例如,可以使用循环。第一步:转换为utf-8编码的字符串/向量/字符数组。Utf-16也可以。@eerorika你能举个例子吗?你熟悉“SQL注入”这个术语吗?当您“使用字符串插入SQL请求而不进行绑定”时,就会发生这种情况。有关更多信息,请参阅询问的问题,即如何将
    std::vector
    转换为
    std::string
    并返回,而不丢失内容。就是这样做的。P.S.@moing,从C++17开始,有符号/无符号转换是定义的行为,当转换回来时,保证返回原始值。祝你今天愉快。C++17:
    [conv.integral]整数类型的prvalue可以转换为另一个整数类型的prvalue。。。结果是目标类型的唯一值,该值与源整数模2^N一致,其中N是目标类型的宽度。
    --省略号位不相关。字符和无符号字符的宽度相同。实际上,转换是双向的。大多数C++编译器都已经做了几十年的工作,C++ 17简单地将现有的实践形式化了。MySQL的代码< BLUB</COD>数据类型被设计用于存储二进制数据。在$dayjob$我们在那里储存了大量的东西,比如gzipped柏油球等。PDF文件。使用绑定变量和blob列。最后,“blob绑定”所做的就是让mysql客户端库正确引用并缩放绑定变量的内容,以替换
    占位符。这就是它的全部功能。当然欢迎你自己这么做,但我认为这样做毫无意义,除了为虫子创造繁殖机会。这就是绑定变量的用途。而且,我确实看到,显示的SQL确实无法正确引用字符串,并引发了SQL注入攻击。正确的解决方案是始终使用绑定变量,这是信息安全领域的任何人都会告诉您的。我还将研究使用7bit编码而不是base64编码,这会将数据压缩17%以上。如果有长数组的无符号字符,会发生什么?这是一个关于3个无符号字符的示例,但如果向量中有1024个,它将如何将数据压缩17%?你能解释一下吗?如果你能用你的想法和编码的例子来回答这个问题,我会很高兴。谢谢如果向量有1024个
    无符号字符
    ,那么将其转换为基数64将产生一个包含1366个字符的字符串。将其转换为7位编码只需要1170个字符。但我也想到,只要您始终使用相同的编译器/设置/操作系统,那么对于1024个字符的字符串,您实际上可以使用完整的8位。我制作了一个输入迭代器,可以安全地绕过未定义的行为来保留所有8位:。注意:这在字符串中看起来很有趣,因为字节并非都是可见字符,在数据库中看起来也很有趣,数据库可能会将字符串重新编码为UTF8或其他内容,但无论如何它都是有效和安全的。