提问人:Kevinkun 提问时间:8/29/2021 更新时间:8/30/2021 访问量:417
无符号字符 * 产生奇怪的字符,使其始终无法比较
Unsigned char * produce weird characters which make it always failed to compared
问:
我总是有这个问题,尤其是当它是从某个函数返回的类型时。我的问题是,我有一个数据库,我想从表中选择其中一列。然后用 获取值。unsigned char*
sqlite3_column_text()
这是代码:
void check_username(std::string username)
{
sqlite3_stmt* stmt;
std::string query = "SELECT username FROM bank_account WHERE username = '"+ username +"';";
int rc = sqlite3_prepare_v2(DB, query.c_str(), -1, &stmt, NULL);
if (rc != SQLITE_OK)
{
std::cerr << "Error: " << sqlite3_errmsg(DB) << std::endl;
return -1;
}
// Move to result of query's row
rc = sqlite3_step(stmt);
// Get the column value
const unsigned char* result = sqlite3_column_text(stmt, 0);
// Convert std::string username to unsigned char* for comparison with text in result
const unsigned char* new_username = reinterpret_cast<const unsigned char*>(username.c_str());
sqlite3_finalize(stmt);
// THIS WILL FAILED TO COMPARE //
if (new_username == result)
std::cout << "It's match! << std::endl;
else
std::cout << "It's not match! << std::endl;
}
它说返回,所以这就是为什么我将其存储在相同类型的变量中:sqlite3_column_text()
unsigned char*
const unsigned char* result = sqlite3_column_text(stmt, 0);
然后正如你所看到的,我的函数作为参数。因此,为了将其与数据库的结果进行比较,我将其转换为无符号字符:std::string
const unsigned char* new_username = reinterpret_cast<const unsigned char*>(username.c_str());
问题来了:在代码的末尾,它总是无法比较,即使名称匹配,它也总是会变成假。然后我尝试调试,这是输出:std::cout << result << std::endl;
std::cout << new_username << std::endl;
�S�U
Harrypotter
所以从中产生的那个奇怪的字符。所以,我认为这就是为什么当我试图比较时它总是不匹配的原因。sqlite3_column_text()
所以我的问题是,这是怎么发生的?有什么解决方案可以让我进行比较?
答:
喜欢这个:
void check_username(const std::string& username) // added const&
{
....
// Get the column value, create string from char*
std::string new_username{ static_cast<const char*>(sqlite3_column_text(stmt, 0)) }; // <========
sqlite3_finalize(stmt);
// now compare the std::string variables instead of pointers
if (new_username == username)
std::cout << "It's match! << std::endl;
else
std::cout << "It's not match! << std::endl;
}
评论
sqlite3_column_text()
std::string
no instance of constructor "std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string [with _CharT=char, _Traits=std::char_traits<char>, _Alloc=std::allocator<char>]" matches the argument list -- argument types are: (const unsigned char *)
在这一行中:
if (new_username == result)
您不能像这样比较两个单独的指针。指针本质上只是
内存地址,并考虑到并引用内存中的不同位置,上述条件将永远无法满足。result
new_username
如果要比较内容,有三个选项:
-
#include <cstring> #include <algorithm> // Do prefer using `const std::string&` over just `std::string` in the parameter to avoid temporary copies void check_username(std::string const& username) { // ... const unsigned char* result = sqlite3_column_text(stmt, 0); // ... if (std::equal(username.begin(), username.end(), result, result + std::strlen(reinterpret_cast<const char*>(result)))) std::cout << "It's match!" << std::endl; else std::cout << "It's not match!" << std::endl; }
对字符串使用
operator==()
比较运算符:#include <cstring> // ... void check_username(std::string const& username) { // ... const unsigned char* result = sqlite3_column_text(stmt, 0); // ... if (username == std::string(result, result + std::strlen(reinterpret_cast<const char*>(result)))) std::cout << "It's match!" << std::endl; else std::cout << "It's not match!" << std::endl; }
-
#include <cstring> // ... void check_username(std::string const& username) { // ... const unsigned char* result = sqlite3_column_text(stmt, 0); // ... if (std::strcmp(&username[0], reinterpret_cast<const char*>(result)) == 0) std::cout << "It's match!" << std::endl; else std::cout << "It's not match!" << std::endl; }
评论
username
result
std::cout
sqlite3_finalize(stmt)
result
评论