0

I'm making a RPG item/magic manager, and I'm trying to handle the case if the person choose a number that does not exist, but mysql_fetch_row keeps returning NULL when it runs for the second time.

I think I would need to run res = mysql_store_result(conn); again, but it gives me this error if I try to run it inside the second while:

An exception was thrown at 0x00007FF82E124216 (libmysql.dll) (in rpg.exe): 0xC0000005: An access violation occurred while reading location 0x0000000000000010

This is my current code:

void listarPersonagem(MYSQL* conn) {
    MYSQL_ROW row;
    MYSQL_RES* res;

    std::string query = "SELECT * FROM personagem";
    const char* q = query.c_str();

    qstate = mysql_query(conn, q);

    int escolha = -1;
    std::map<int, int> indexMap;

    if(!qstate) {
        res = mysql_store_result(conn);

        signed int fields = static_cast<int>(mysql_num_rows(res));
        while(escolha < 0 || escolha > fields) {

            system("cls");
            std::cout << "\t\t\t\t Personagens\n" << std::endl;

            indexMap = {};

            int i = 1;
            while(row = mysql_fetch_row(res)) { //It returns NULL and doesn't run
                std::cout << i << " - " << row[1] << std::endl; 
                indexMap.insert({i, std::atoi(row[0])});
                i++;
            }

            std::cout << "0 - Voltar" << std::endl;


            std::cout << "\n\n=>";
            std::cin >> escolha;

        }
    }

    int id = escolha != 0 ? indexMap[escolha] : 0;

    row = NULL;
    res = nullptr;
    qstate = NULL;
}

Informations that may be useful:
IDE: Visual Studio 2019
OS: Windows 10

Yasushiki
  • 11
  • 3
  • only one store result per query and what is the use of `while(escolha < 0 || escolha > fields) {` if `mysql_fetch_row(res)` hasn' a result or is at its end it will stop automatically – nbk Nov 02 '21 at 23:59
  • `while(escolha < 0 || escolha > fields) {` is to make sure that `escolha` is between 0 (to go back) and the last row element, so if there are 5 elements and the user enter 6, it will run/print again and wont get an error or something like that. – Yasushiki Nov 03 '21 at 00:18

1 Answers1

0

I figured out how to "rerun" mysql_fetch_row. All I did was change the while to an if to check the value entered by the user and change this function type to int, so I can tell what happened and know if I need to run it again.

int listarPersonagem(MYSQL* conn) {
    MYSQL_ROW row;
    MYSQL_RES* res;

    std::string query = "SELECT * FROM personagem";
    const char* q = query.c_str();

    qstate = mysql_query(conn, q);

    int escolha = -1;
    std::map<int, int> indexMap;

    if(!qstate) {
        res = mysql_store_result(conn);

        system("cls");
        std::cout << "\t\t\t\t Personagens\n" << std::endl;

        indexMap = {};

        int i = 1;
        while(row = mysql_fetch_row(res)) {
            std::cout << i << " - " << row[1] << std::endl;
            indexMap.insert({i, std::atoi(row[0])});
            i++;
        }

        std::cout << "0 - Voltar" << std::endl;


        std::cout << "\n\n=>";
        std::cin >> escolha;
        
        signed int fields = static_cast<int>(mysql_num_rows(res));
        if(escolha < 0 || escolha > fields) {
            return -1; // if the number doesn't exist, it will return -1

        }

    }

    int id = escolha != 0 ? indexMap[escolha] : 0;

    row = NULL;
    res = nullptr;
    qstate = NULL;
    

    return 0;
}
switch(escolha) {
    // sair
    case 0:
        return 0;

    // ver personagens
    case 1:
        escolha = listarPersonagem(conn) == 0 ? -1 : 1; // if the function returns -1, it will be runned again
        break;
Yasushiki
  • 11
  • 3