You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pqxx库从数据库提取用户名触发C++ xstring报错如何解决

报错根因

你触发xstring报错的直接原因是LoginUser函数内的SQL拼接逻辑存在严重错误:

  • 代码里写的'user'是C++多字节字符字面量,会被编译器处理为int类型,你把SQL字符串常量的指针与这个int值相加,相当于直接访问了字符串后方的非法内存,std::string构造时触发内存越界才会抛出xstring相关错误。
  • 你没有用传入的user参数拼接SQL,反而用了固定的字符字面量,就算不崩也查不到正确数据。
  • 现有直接拼接SQL的写法还存在SQL注入风险,且需要手动处理字符串转义、引号包裹等逻辑,非常容易出错。

修正后的实现代码

1. 登录功能修正(含数据读取逻辑)

void DBUser::LoginUser(std::string const& user, std::string const& pw)
{
    pqxx::work worker(*DBLink::GetInstance());
    try {
        // 使用pqxx参数化查询,$1对应第一个传入参数,自动处理类型转义和引号
        pqxx::result query_res = worker.exec_params(
            "SELECT username, password FROM users WHERE username = $1",
            user
        );
        worker.commit();

        // 读取结果逻辑
        if (query_res.empty()) {
            throw std::runtime_error("用户名不存在");
        }
        // 取第一行结果,通过字段名读取值并转为std::string
        std::string db_username = query_res[0]["username"].as<std::string>();
        std::string db_encrypted_pw = query_res[0]["password"].as<std::string>();

        // 后续密码校验逻辑:加密传入的pw后和db_encrypted_pw对比即可
    }
    catch (const std::exception& e) {
        worker.abort();
        throw;
    }
}

2. 创建用户功能修正(避免SQL注入)

void DBUser::CreateUser(std::string const& user, std::string const& pw)
{
    pqxx::work worker(*DBLink::GetInstance());
    try {
        std::string encrypted_pw = worker.conn().encrypt_password(user, pw, "md5");
        // 参数化插入,不需要手动拼接字符串处理引号
        worker.exec0(
            "INSERT INTO users (username, password) VALUES ($1, $2)",
            user,
            encrypted_pw
        );
        worker.commit();
    }
    catch (const std::exception& e) {
        worker.abort();
        throw;
    }
}

pqxx读取查询结果的常用规则

  • pqxx::result是查询返回的结果集容器:
    • 调用empty()可判断是否有返回数据
    • 调用size()可获取返回的行数
  • 访问具体行:通过下标result[行号]即可拿到pqxx::row对象,行号从0开始计数
  • 读取行内字段支持两种方式:
    • 按字段名读取:row["字段名"].as<目标类型>()
    • 按字段位置读取:row[字段下标].as<目标类型>(),下标从0开始计数
  • 如果你确定查询只会返回一行数据,可以直接用exec1代替exec_params,直接拿到pqxx::row对象,不需要自己从result里取第一行。

内容的提问来源于stack exchange,提问作者Vasile Mihai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 21:45:05