古月不傲 发表于 2020-12-11 19:09

简单单词背诵

本帖最后由 古月不傲 于 2020-12-13 04:38 编辑

#include <iostream>
#include <mysql/mysql.h>
#include <mutex>
#include <string>
#include <vector>
#include <iomanip>

namespace wind
{
#define COMMAND_BUF_SIZE 256

    // 状态
    enum Flags
    {
      SHOW,       // 只显示数据
      FIRST,      // 第一次全部读取数据
      SECOND      // 第二次直接读取表单最后一行插入数组 提高效率
    };
    // 数据
    struct Data
    {
      std::string strEnglish;
      std::string strChinese;
    };
    // 数据库
    class Mysql
    {
    private:
      MYSQL       m_mysql;
      std::mutexm_mutex;
      std::string m_strRoot;
      std::string m_strUser;
      std::string m_strPassword;
      std::string m_strDatabase;
      std::string m_strTableName;
      int         m_nPost;
      char      m_commandBuf{};
      std::vector<std::string> m_chineseWords;
    public:
      // +--------------------+
      // | id english chinese |
      // | 1    苹果   apple   |
      // | 2    香蕉   banana|
      // +--------------------+
      // 获取中文
      inline std::vector<std::string> getChineseWords() const
      {
            return this->m_chineseWords;
      }
      // 初始化数据库
      bool init(const std::string &strRoot, const std::string &strUser, const std::string &strPassword, const std::string &strDatabase, const std::string &strTableName, int nPort)
      {
            // 隐式构造(形参) + 移动构造(提升效率)
            this->m_strRoot         = std::move(strRoot);
            this->m_strUser         = std::move(strUser);
            this->m_strPassword   = std::move(strPassword);
            this->m_strDatabase   = std::move(strDatabase);
            this->m_strTableName    = std::move(strTableName);
            this->m_nPost         = nPort;

            if ((mysql_init(&this->m_mysql)) == nullptr)
            {
                printf("%s.%d error!\n", __func__, __LINE__);
                return false;
            }
            std::lock_guard<std::mutex> lockguard(this->m_mutex);
            if ((mysql_library_init(0, nullptr, nullptr)) != 0)
            {
                printf("%s.%d error!\n", __func__, __LINE__);
                return false;
            }
            return true;
      }
      // 连接数据库
      bool connect()
      {
            // 连接数据库
            if ((mysql_real_connect(&this->m_mysql, this->m_strRoot.data(), this->m_strUser.data(),
                this->m_strPassword.data(), this->m_strDatabase.data(), m_nPost, nullptr, 0)) == nullptr)
                return false;

            // 设置字符集
            if (mysql_query(&this->m_mysql, "set names utf8"))
            {                  
                printf("%s.%d %s\n", __func__, __LINE__, mysql_error(&this->m_mysql));
                return false;
            }
            sprintf(this->m_commandBuf, "use %s", this->m_strDatabase.data());
            // 使用哪一个数据库
            if (mysql_query(&this->m_mysql, this->m_commandBuf))
            {
                printf("%s.%d %s\n", __func__, __LINE__, mysql_error(&this->m_mysql));
                return false;
            };
            return true;
      }
      // 插入数据库
      bool insert(const Data &data)
      {
            if (this->m_strTableName.empty() || data.strEnglish.empty() || data.strChinese.empty())
                return false;

            sprintf(this->m_commandBuf, "insert into %s(english, chinese) values('%s', '%s')",
                  this->m_strTableName.data(), data.strEnglish.data(), data.strChinese.data());
            if (mysql_query(&this->m_mysql, m_commandBuf))
            {
                printf("%s.%d %s\n", __func__, __LINE__, mysql_error(&this->m_mysql));
                return false;
            }
            return true;
      }
      // 查询数据
      bool querys(Flags flags)
      {
            MYSQL_RES *results;
            MYSQL_FIELD *fields;
            MYSQL_ROW rows;
            unsigned int nNumfields;

            if (flags != SECOND)
            {
                sprintf(this->m_commandBuf, "select *from %s", this->m_strTableName.data());
                if (mysql_query(&this->m_mysql, this->m_commandBuf))
                {
                  printf("%s.%d %s\n", __func__, __LINE__, mysql_error(&this->m_mysql));
                  return false;
                }
                // 获取结果集
                if ((results = (mysql_store_result(&this->m_mysql))) == nullptr)
                {
                  printf("%s.%d error!\n", __func__, __LINE__);
                  return false;
                }
                // 获取一共有多少列
                nNumfields = mysql_num_fields(results);               
                // 只显示数据
                if (flags == SHOW)
                {                  
                  // 获取字段名
                  while (fields = (mysql_fetch_field(results)))
                        std::cout << std::setw(15) << fields->name;

                  std::cout << std::endl;
                  // 循环获取数据
                  while (rows = (mysql_fetch_row(results)))
                  {
                        for (int i = 0; i < nNumfields; ++i)
                        {
                            if (rows)
                              std::cout << std::setw(15) << rows;
                        }
                        std::cout << std::endl;
                  }
                }
                // 全部数据存入数组
                else if (flags == FIRST)
                {
                  while (rows = (mysql_fetch_row(results)))
                  {
                        for (int i = 0; i < nNumfields; ++i)
                            this->m_chineseWords.push_back(rows);
                  }
                }
                return true;
            }
         // 读取最后一行数据 直接放入数组
            if (flags == SECOND)
            {                  
                sprintf(this->m_commandBuf, "select *from %s where id=(select max(id) from %s)", this->m_strTableName.data(), this->m_strTableName.data());
                if (mysql_query(&this->m_mysql, this->m_commandBuf))
                {
                  printf("%s.%d %s\n", __func__, __LINE__, mysql_error(&this->m_mysql));
                  return false;
                }
                // 获取结果集
                if ((results = (mysql_store_result(&this->m_mysql))) == nullptr)
                {
                  printf("%s.%d error!\n", __func__, __LINE__);
                  return false;
                }
                // 因为只有一行数据 所以获取一次即可
                if ((rows = mysql_fetch_row(results)) == nullptr)
                  return false;

                // 放入数组
                this->m_chineseWords.push_back(rows);
            }
            mysql_free_result(results);
            return true;
      }
      // 查询单行数据
      std::vector<std::string> query(const std::string &data, const std::string &from)
      {
            if (data.empty())
                return {};
               
            MYSQL_RES *results;
            MYSQL_ROW rows;

            sprintf(this->m_commandBuf, "select *from %s where chinese = '%s'", this->m_strTableName.data(), data.data());
            if (mysql_query(&this->m_mysql, this->m_commandBuf))
            {
                printf("%s.%d %s\n", __func__, __LINE__, mysql_error(&this->m_mysql));
                return {};
            }
            if ((results = (mysql_store_result(&this->m_mysql))) == nullptr)
               return {};

            rows = mysql_fetch_row(results);               
            if (from == "h")
                return {rows};

            else if (rows == from)
                printf("\033[32mnice!\n\033[0m");

            else
                printf("\033[31merror!\n\033[0m");

            return {};
      }
    public:
      // 单例模式
      static Mysql &getInstance()
      {
            static Mysql mysql;
            return mysql;
      }
    private:
      Mysql() = default;
      Mysql(const Mysql &) = delete;
      const Mysql &operator =(const Mysql &) = delete;
      ~Mysql()
      {
            std::lock_guard<std::mutex> lockGuard(this->m_mutex);
            mysql_library_end();
            mysql_close(&this->m_mysql);
      }
    };
};

int main(void)
{
    srand((unsigned int)(time(nullptr)));
    printf("\033[31mtype(h = help, i = insert)\n\033[0m");

    wind::Mysql::getInstance().init("localhost", "root", "123456", "words","first", 3306);
    wind::Mysql::getInstance().connect();
    // wind::Mysql::getInstance().insert({"apple", "苹果"});
    // wind::Mysql::getInstance().insert({"orange", "橘子"});
    // wind::Mysql::getInstance().insert({"peach", "桃子"});
    // wind::Mysql::getInstance().insert({"pear", "梨子"});
    // wind::Mysql::getInstance().insert({"watermelon", "西瓜"});
    wind::Mysql::getInstance().querys(wind::FIRST);
   
    std::vector<std::string> key;
    std::string value;
    int nLen;

    auto init = [&key, &nLen]()
    {
      // 获取数组 此时数组里面已经存好了中文
      key = wind::Mysql::getInstance().getChineseWords();
      nLen = key.size();
    };

    init();

    while (1)
    {
      value.clear();
      int i = rand() % nLen;
      // 随机从数组里面选择一个中文单词
      printf("Please type the corresponding English %s: ", key.data());      
      std::cin >> value;

      // 显示答案
      if (value == "h")
      {
            auto answer = wind::Mysql::getInstance().query(key.data(), value);
            printf("%s\n", answer.data());
      }   

      // 插入数据
      if (value == "i")
      {
            std::string chi;
            std::string eng;

            printf("english:");
            std::cin >> eng;
            printf("chinese:");
            std::cin >> chi;

            wind::Mysql::getInstance().insert({eng, chi});
            wind::Mysql::getInstance().querys(wind::SHOW);
            init();
            wind::Mysql::getInstance().querys(wind::SECOND);
            continue;
      }
      // 查询输入的数据 是否正确
      wind::Mysql::getInstance().query(key.data(), value);
    }

    return 0;
}

525406902 发表于 2020-12-11 19:29

请问大佬这是什么(ㅇㅁㅇ川

ydx20201111 发表于 2020-12-11 19:46

完全看不懂啊

小晓白 发表于 2020-12-11 20:07

这个怎么用的大哥{:1_924:}

gms 发表于 2020-12-11 20:34

学习了
!!!

qihang5518 发表于 2020-12-11 20:37

能加一下讲解说明就好了,小白确实看不明白

泉水指挥官 发表于 2020-12-11 20:43

小白看不明白

n3iuarem3t 发表于 2020-12-11 21:53

还得用数据库,就不能搞个列表放点你想背的单词?

ligao_1120 发表于 2020-12-11 22:09

这个应该是源码!没封装!累眼看着

wanshiz 发表于 2020-12-12 07:40

谢谢楼主分享这么多。得花些时间看看。
页: [1] 2
查看完整版本: 简单单词背诵