我使用VS 2010 Professional在C ++中进行编程,但我遇到了这个问题:
如果程序启动且连接良好,则会加载" gameactive"循环,并显示播放器的高分。
但是当连接出错时,它会冻结并崩溃。我想显示一个错误,如"错误连接到服务器"并继续加载游戏。
我确实使用过这个教程: http://r3dux.org/2010/11/how-to-use-mysql-connectorc-to-connect-to-a-mysql-database-in-windows/
这是我的代码:
// Standad C++ includes
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
#include <string.h>
// Include the Connector/C++ headers
#include "cppconn/driver.h"
#include "cppconn/exception.h"
#include "cppconn/resultset.h"
#include "cppconn/statement.h"
#include <cgl\cgl.h>
#include <cgl\core.h>
#include <core\corefile.h>
// Link to the Connector/C++ library
#pragma comment(lib, "mysqlcppconn.lib")
// Specify our connection target and credentials
const string server = "tcp://xxx.xxx.xxx.xxx:3306";
const string username = "xxxxxxx";
const string password = "XXxxXXxxXXxx";
char myoutput[1024];
char myoutput1[1024];
char myoutput2[1024];
s_font font;
s_bitmap bmp_background;
int connectsetup()
{
sql::Driver *driver; // Create a pointer to a MySQL driver object
sql::Connection *dbConn; // Create a pointer to a database connection object
sql::Statement *stmt; // Create a pointer to a Statement object to hold our SQL commands
sql::ResultSet *res; // Create a pointer to a ResultSet object to hold the results of any queries we run
// Try to get a driver to use to connect to our DBMS
try
{
driver = get_driver_instance();
}
catch (sql::SQLException e)
{
cout << "Could not get a database driver. Error message: " << e.what() << endl;
}
// Try to connect to the DBMS server
try
{
dbConn = driver->connect(server, username, password);
}
catch (sql::SQLException e)
{
cout << "Could not connect to database. Error message: " << e.what() << endl;
}
stmt = dbConn->createStatement(); // Specify which connection our SQL statement should be executed on
// Try to query the database
try
{
stmt->execute("USE runner"); // Select which database to use. Notice that we use "execute" to perform a command.
res = stmt->executeQuery("SELECT * FROM highscores"); // Perform a query and get the results. Notice that we use "executeQuery" to get results back
}
catch (sql::SQLException e)
{
cout << "SQL error. Error message: " << e.what() << endl;
}
// While there are still results (i.e. rows/records) in our result set...
while (res->next())
{
// ...get each field we want and output it to the screen
// Note: The first field/column in our result-set is field 1 (one) and -NOT- field 0 (zero)
// Also, if we know the name of the field then we can also get it directly by name by using:
// res->getString("TheNameOfTheField");
//printf(myoutput,"%s %s %s",res->getString(1),res->getString(2),res->getString(3));
strcpy(myoutput,res->getString(1).c_str());
strcpy(myoutput1,res->getString(2).c_str());
strcpy(myoutput2,res->getString(3).c_str());
}
// Clean up after ourselves
delete res;
delete stmt;
delete dbConn;
return 0;
}
void coremain()
{
//Fullscreen, windowed of scaled?
corefile_mountimage("res",MOUNT_DIR);
CGL_InitVideo(1280, 720, CGL_VIDEO_NONE);
CGL_SetTitle("CGL - Endless poepert");
CGL_InitFont("font_heat.tga", &font);
CGL_LoadBitmap("track1.tga",&bmp_background);
connectsetup();
int gameactive=1;
int getal=atoi(myoutput);
do {
do {
CGL_WaitRefresh();
CGL_DrawBitmap(0,0,bmp_background);
CGL_DrawCenteredText(100,font, "%s: %d van %s score %s",myoutput,getal,myoutput1,myoutput2);
int key,keytrig;
CGL_GetKeys(&key,&keytrig);
if (keytrig & CGL_INPUT_KEY_EXIT) exit(EXIT_SUCCESS);
CGL_SwapBuffers();
} while(gameactive);
CGL_FlushGraphics();
} while(1);
CGL_CloseVideo();
}
答案 0 :(得分:0)
问题似乎是您的connectSetup
功能。您有try/catch
个区块,但如果出现问题,您就无法执行任何操作。你只是继续前进,好像什么都没有错。
此外,这是学习智能指针的好时机。这里应该使用智能指针的原因是即使数据库连接成功也会出现问题(你有后续的try / catch块)。您希望确保清除已分配的任何内容,无论您何时何地发出return
语句。
#include <memory>
#include <string>
std::string myoutput;
std::string myoutput1;
std::string myoutput2;
int connectsetup()
{
sql::Driver* driver;
std::unique_ptr<sql::Connection> dbConn;
std::unique_ptr<sql::Statement> stmt;
std::unique_ptr<sql::ResultSet> res;
try
{
driver = get_driver_instance();
dbConn.reset(driver->connect(server, username, password))
stmt.reset(dbConn->createStatement());
stmt->execute("USE runner");
res.reset(stmt->executeQuery("SELECT * FROM highscores")); // Perform a query
while (res->next())
{
myoutput = res->getString(1);
myoutput1 = res->getString(2);
myoutput2 = res->getString(3);
}
}
catch (const sql::SQLException& e)
{
cout << "Something went wrong with the database stuff. Here it is: " << e.what() << endl;
return -1;
}
return 0;
}
此代码未编译,但我尝试提取您的原始代码正在执行的操作,并使用智能指针重写它。
如果任何这些语句失败,上面的代码将抛出异常。请注意,我们通过reference
捕获异常,而不是按值捕获异常。另请注意,不需要delete
,因为std::unique_ptr
会自动执行此操作。
最后,不需要char数组 - 为什么要引入它们?它只会使你的函数的另一部分容易受到内存覆盖,即在res->next()
循环中。