我刚开始使用c ++,在阅读了一些教程后,我正在尝试使用数据库创建一个简单的myqsl连接。请记住,我主要是一个Web开发人员,因此这对我来说是一个新事物。我目前的代码(取自教程)是这样的:
#include <mysql.h>
#include <stdio.h>
#include <stdlib.h>
//#include <string>
using namespace std;
struct connection_details
{
char *server;
char *user;
char *password;
char *database;
};
MYSQL* mysql_connection_setup(struct connection_details mysql_details) {
MYSQL *connection = mysql_init(NULL);
if (!mysql_real_connect(connection,mysql_details.server, mysql_details.user, mysql_details.password, mysql_details.database, 0, NULL, 0)) {
printf("Conection error : %s\n", mysql_error(connection));
exit(1);
}
return connection;
}
MYSQL_RES* mysql_perform_query(MYSQL *connection, char *sql_query) {
if (mysql_query(connection, sql_query)) {
printf("MySQL query error : %s\n", mysql_error(connection));
exit(1);
}
return mysql_use_result(connection);
}
int main() {
MYSQL *conn; // the connection
MYSQL_RES *res; // the results
MYSQL_ROW row; // the results row (line by line)
struct connection_details mysqlD;
mysqlD.server = "localhost"; // line 46
mysqlD.user = "root"; // line 47
mysqlD.password = "root"; // line 48
mysqlD.database = "backseat"; // line 49
conn = mysql_connection_setup(mysqlD);
res = mysql_perform_query(conn, "show tables"); // line 53
printf("MySQL Tables in mysql database:\n");
while ((row = mysql_fetch_row(res)) !=NULL)
printf("%s\n", row[0]);
mysql_free_result(res);
mysql_close(conn);
return 0;
}
然而g ++给了我以下警告:
main.cpp:46:19: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:47:17: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:48:21: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:49:21: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:53:48: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
虽然程序有效,但目前我的理解还不够。 我为删除警告所做的工作如下:
char s[] = "localhost";
char u[] = "root";
char p[] = "root";
char d[] = "backseat";
然后
mysqlD.server = s;
mysqlD.user = u;
mysqlD.password = p;
mysqlD.database = d;
这照顾了警告,但我认为必须有一个更好的方法&amp;解释我应该如何照顾这个。 而且我试着用:
struct connection_details
{
string *server;
string *user;
string *password;
string *database;
};
但是这并没有注意到第53行的警告加上所有地狱之后都松了一口气。 我的问题是我应该如何处理简单的mysql连接,为什么会出现这些警告,并且在结构中使用字符串是一个坏主意?
我很抱歉这篇长篇文章,但我在这里和学习曲线上有很多东西需要考虑。
PS:任何好的教程/指南都将不胜感激。谢谢。
答案 0 :(得分:1)
你遗漏了一些基础知识。我不知道要链接的好教程,但我会解释你做错了什么:
首先,当您编写C ++时,应使用string
而不是char*
。你应该阅读char*
的详细信息;它是一个指针,因此处理它与处理string
。
您的代码中发生的事情是您将 字符串文字的地址(如"localhost"
)分配给char*
(因为它是指针)。问题是,gcc将字符串文字转换为常量,这些常量是只读的(如警告所示)。然而,类型char*
意味着可以更改字符串的内容。将类型更改为const char*
以消除警告。
以下是一些代码来说明问题:
char* a;
const char* b;
a = "foo";
b = "bar";
a[0] = 'a'; // you're changing the constant string!
b[0] = 'b'; // compiler error; b is const
a = "foz"; // both allowed because you're not changing
b = "baz"; // the string, but only the pointer
更简单的选择是使用string
:
struct connection_details
{
string server;
string user;
string password;
string database;
}
你不应该在这里使用指针。 string
在内部管理低级内存。现在的问题是你正在使用C级MySQL绑定,它需要char*
而不是string
。要在代码中使用string
时调用它,请使用c_str()
进行转换:
connection.server.c_str()
等等。
或者,您可能希望使用更高级别的C ++ API连接到MySQL。如果您正在学习C ++,那么如果可能的话,最好避免使用C API。例如,有MySQL++,但我不知道,因此无法推荐它。 SOCI提供了更高级别的API,它适用于多个数据库后端(包括MySQL)。