linux下 c++ 生成sql 存入數據庫亂碼

如題,被這個問題困擾了好久。

1. 客戶端發來了數據,在terminal中輸出,顯示的中文正常。

2. 在網上搜索後,發現可能是mysql的設置問題,於是設置了mysql的配置文件,將所有的字符集都設置爲utf8

     嘗試了重啓服務,但是並沒有生效,當時很是無語,但是關機後,第二天開機就生效了(無奈)。

3. 當mysql所有的字符集設置成utf8後,程序中添加到mysql中的中文還是亂碼。

4. 在terminal下面使用 mysql -uroot -p 登陸後,查看 show variables like 'character%';的設置都爲utf8,嘗試添加中文,顯示均爲正常

5. 回到程序中,問題仍然存在。

6. 在ide下面 cout << sql << endl; 也是現實的正常。


於是剛剛換了個思路,思考是否是與系統本身的字符集有關,或者是標準c++ 語言有關,可是這個年頭很快就被打消了。

在windows下的api還有A版和W版的區別,因此不會是由於語言本身造成的。

然後就看到了這篇文章 http://outofmemory.cn/code-snippet/3583/linux-cpp-connect-mysq

在文章中有這樣一段代碼

#include <iostream>
using namespace std;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <syslog.h>
#include <iconv.h>
int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen)
{
    iconv_t cd;
    int rc;
    char **pin = &inbuf;
    char **pout = &outbuf;

    cd = iconv_open(to_charset,from_charset);
    if (cd==0) return -1;
    memset(outbuf,0,outlen);
    size_t in_buf=inlen;
    size_t out_buf=outlen;
    if (iconv(cd,pin,&in_buf,pout,&out_buf)==-1) return -1;
    iconv_close(cd);
    return 0;
}

int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
    return code_convert((char *)"utf-8",(char *)"gb2312",inbuf,inlen,outbuf,outlen);
}
int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
    return code_convert((char *)"gb2312",(char *)"utf-8",inbuf,inlen,outbuf,outlen);
}

int main()
{
    MYSQL mysql;
    char host[32] = "127.0.0.1";
    char user[32] = "root";
    char passwd[32] = "763092";
    char db[32] = "my_db";

    if( mysql_init(&mysql) == NULL )
    {
        fprintf(stderr,"Init mysql err!");
        return -1;
    }
    if (mysql_real_connect(&mysql,host,user,passwd,db,0,NULL,0) == NULL)
    {
        fprintf(stderr,"Connect to mysql Error:%s! \n",mysql_error(&mysql));
        return -1;
    }
    else
    {
        puts("Connect to mysql success! \n");
    }

    mysql_query(&mysql,"set names 'GBK'");       //// 這行很重要,向你的程序說明,是以GBK字符集連接到MYSQL數據庫,如果數據庫使用的是utf8,這裏改爲 "set names 'utf8'"

    MYSQL_ROW m_row;
    MYSQL_RES *m_res;

    char sql[1024];
    char out_buf[128];
    char in_buf[]="中國zhongguo";         
    u2g(in_buf,strlen(in_buf),out_buf,sizeof(out_buf));    //轉爲gbk 字符集 存在out_buf 中

    sprintf(sql,"insert into test (name,age) values('%s',21)",in_buf);
    mysql_query(&mysql,sql);       // 把gbk 內容存到數據庫當中去,   注意 數據庫當中此例的字符集一定要爲gbk2312

    sprintf(sql,"select * from test");
    if(mysql_query(&mysql,sql) != 0)
    {
        fprintf(stderr, "mysql_query err: %s \n",mysql_error(&mysql));
    }

    m_res = mysql_store_result(&mysql);

    if(m_res==NULL)
    {
        fprintf(stderr, "get result err: %s",mysql_error(&mysql));
    }
    while(m_row = mysql_fetch_row(m_res))
    {
        bzero(out_buf,sizeof(out_buf));
        g2u(m_row[1],strlen(m_row[1]),out_buf,sizeof(out_buf));    // 查出來,要對其進行轉換爲utf-8,不然控制檯不能正常 顯示
        printf(" %d , %s , %d \n",atoi(m_row[0]),out_buf,atoi(m_row[2]));
    }

    mysql_free_result(m_res);
    mysql_close(&mysql);
        return 0;
}

突然就注意到了這篇文章中, 在mysql_real_connect 之後 有一句 mysql_quer(&mysql, "set names utf8"); 表明鏈接數據庫時用utf8
可是我之前也有在terminal下面 設置過呀, 可是問題沒解決呀?
恍然大悟,其實問題是解決了,在terminal下面輸入中文是一點問題都沒有的。而在terminal下面連接數據庫之後,terminal就相當於一個client,在terminal下面
進行的設置是跟程序本身分開的。


於是在自己的程序中也進行了這樣的設置,然後問題就solved了!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章