CS/데이터베이스

[MySQL] Visual studio 연동 - 한글 인코딩

nowkoes 2023. 7. 13. 15:49

한글 인코딩

개요

#include <iostream>
#include <mysql.h>
#include <string>

int main()
{
    MYSQL mysql;
    mysql_init(&mysql);

    if (!mysql_real_connect(&mysql, "localhost", "root", "malove8466", "Team_Creator_example", 3306, NULL, 0))
    {
        std::cout << "Failed to connect to MySQL." << std::endl;
        return 1;
    }

    std::string name = "이름";
    std::string id = "닉네임";
    int wins = 3;
    int losses = 1;

    std::string query = "INSERT INTO users (name, id, wins, losses) VALUES ('" + name + "', '" + id + "', " + std::to_string(wins) + ", " + std::to_string(losses) + ")";
    if (mysql_query(&mysql, query.c_str()) != 0)
    {
        std::cout << "Query execution error: " << mysql_error(&mysql) << std::endl;
        return 1;
    }

    std::cout << "New record added successfully." << std::endl;
    mysql_close(&mysql);

    return 0;
}

 

 SQL 쿼리를 작성하는 과정에서 올바르지 않은 문자열 값을 사용했다는 오류가 발생하였다. 이러한 문제는 한글 인코딩 문제에서 기인하는데, 특히 다양한 언어의 문자들을 정확하게 표현하기 위해 필요한 다국어 인코딩인 UTF-8과 같은 형식을 사용하면 자주 겪게 된다.

 

 MySQL 데이터베이스와 연동하는 코드에서 이런 문제가 발생했다면, 우리는 어떻게 이를 해결할 수 있을까? 이번 시간에는 이를 해결하는 방법에 대해 알아보도록 하자.


원인

 앞서 개요에서 살펴봤듯이 이 문제의 원인은 문자열 값이 MySQL 서버에 전달될 때 올바른 인코딩을 사용하지 않기 때문에 발생한다. 인코딩에 대한 자세한 내용은 여기를 참고하자. 인코딩이 잘못 설정되면, 문자열 데이터가 데이터베이스에 저장될 때 잘못된 형식으로 변환될 수 있다. 이 경우, 데이터베이스에 저장된 문자열 데이터는 의도한 값과 다르게 될 수 있다.

 

 MySQL에서는 클라이언트와 서버 간의 통신을 위해 특정 문자 집합을 사용하도록 설정되어 있다. 이 설정은 MySQL 서버와 클라이언트 모두에 영향을 미친다. 서버 설정은 모든 클라이언트 연결에 적용되며, 클라이언트 설정은 해당 클라이언트에서 실행되는 쿼리에만 적용된다.

 예를 들어, 클라이언트는 UTF-8 인코딩을 사용하고 있지만, 서버는 Latin-1 인코딩을 사용하고 있다면, 클라이언트가 서버에 데이터를 전송할 때 데이터가 깨질 수 있다. UTF-8은 한글과 같은 여러 문자를 포함할 수 있는 반면, Latin-1은 주로 서유럽 언어를 위한 문자만을 포함하고 있기 때문이다. 이런 경우, 클라이언트와 서버의 인코딩 설정을 동일하게 맞추는 것이 중요하다. 


해결

 오류를 다시 한 번 살펴보면, C0xCCxB8xA7이라는 오류를 MySQL에서 반환하고 있다. 이는 '이름'을 EUC-KR 혹은 CP949 인코딩으로 변환한 바이트다. 따라서 '이름' 문자열이 EUC-KR로 인코딩되어 있지만, MySQL 클라이언트나 서버는 이를 UTF-8로 해석하려 하고 있어 오류가 발생하고 있다.

 

 따라서 우리는 MySQL에서 문자열 집합을 utf8로 사용하도록 지정하고, 문자열 리터럴을 UTF-8로 인코딩하도록 명시적으로 지정하면 이를 해결할 수 있다. C++11 부터는 이를 위해 u8 접두어를 지원한다.

 

mysql_set_character_set(&mysql, "utf8");

std::string name = u8"이름";
std::string id = u8"닉네임";

 

총합본

#include <iostream>
#include <mysql.h>
#include <string>

int main()
{
    MYSQL mysql;
    mysql_init(&mysql);
    mysql_set_character_set(&mysql, "utf8");

    if (!mysql_real_connect(&mysql, "localhost", "root", "malove8466", "Team_Creator_example", 3306, NULL, 0))
    {
        std::cout << "Failed to connect to MySQL." << std::endl;
        return 1;
    }

    std::string name = u8"이름";
    std::string id = u8"닉네임";
    int wins = 3;
    int losses = 1;

    std::string query = "INSERT INTO users (name, id, wins, losses) VALUES ('" + name + "', '" + id + "', " + std::to_string(wins) + ", " + std::to_string(losses) + ")";
    if (mysql_query(&mysql, query.c_str()) != 0)
    {
        std::cout << "Query execution error: " << mysql_error(&mysql) << std::endl;
        return 1;
    }

    std::cout << "New record added successfully." << std::endl;
    mysql_close(&mysql);

    return 0;
}
반응형