2015-04-06 3 views
0

У меня есть собственный формат файла (базы данных), который я в настоящее время пытаюсь перенести в базу данных SQL. Поэтому я конвертирую файлы в дамп sql, который уже работает нормально. Единственная проблема, оставленная сейчас, - это их странный способ обработки символов, которые не входят в ASCII-десятичный диапазон от 32 до 126. У них есть коллекция всех этих символов, хранящихся в Unicode (hex - eg 20AC = €), индексированных по их собственным внутренний индекс.Напишите UTF8 представление Unicode в файл

Мой план сейчас: Я хочу создать таблицу, в которой сохранен внутренний индекс, юникод (в шестнадцатеричном формате) и представление символа (UTF-8). Затем эту таблицу можно использовать для будущих обновлений.

К проблеме: Как написать символьное представление UTF-8 шестнадцатеричного значения юникода в файл? Текущий код выглядит следующим образом:

this->outFile.open(fileName + ".sql", std::ofstream::app); 
std::string protyp; 
this->inFile.ignore(2); // Ignore the ID = 01. 
std::getline(this->inFile, protyp); // Get the PROTYP Identifier (e.g. \321) 
protyp = "\\" + protyp; 

std::string unicodeHex; 
this->inFile.ignore(2); // Ignore the ID = 01. 
std::getline(this->inFile, unicodeHex); // Get the Unicode HEX Identifier (e.g. 002C) 

std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; 
const std::wstring wide_string = this->s2ws("\\u" + unicodeHex); 
const std::string utf8_rep = converter.to_bytes(wide_string); 

std::string valueString = "('" + protyp + "', '" + unicodeHex + "', '" + utf8_rep + "')"; 

this->outFile << valueString << std::endl; 

this->outFile.close(); 

Но это просто печатает что-то вроде этого:

('\321', '002C', '\u002C'), 

Хотя желаемый результат будет:

('\321', '002C', ','), 

Что я делаю не так? Я должен признать, что я не уверен, когда дело доходит до кодировки символов и т. Д. /. Я работаю над Windows 7 64bit, если это имеет значение. Спасибо заранее.

+0

преобразование из '\ u002C' до величины широких символов происходит во время компиляции, а не время выполнения. Вам нужно забыть о '\ u' и преобразовать строку в целое число. –

+0

Это работает! Большое спасибо. Вы можете добавить свой комментарий в качестве ответа, если хотите. Я соглашусь, как только смогу. Я также добавлю код в качестве второго ответа, чтобы представить решение, которое я придумал. – puelo

+0

Моя цель состояла в том, чтобы дать вам достаточно информации, чтобы получить ответ самостоятельно, и, похоже, мне это удалось. Ваша искренняя благодарность - это все, что мне нужно. –

ответ

1

Как @Mark Ransom указал в комментариях, лучшим вариантом было преобразовать шестнадцатеричную строку в целое и использовать ее. Это то, что я сделал:

unsigned int decimalHex = std::stoul(unicodeHex, nullptr, 16);; 

std::string valueString = "('" + protyp + "', '" + unicodeHex + "', '" + this->UnicodeToUTF8(decimalHex) + "')"; 

В то время как функция для UnicodeToUTF8 была взята отсюда Unsigned integer as UTF-8 value

std::string UnicodeToUTF8(unsigned int codepoint) 
{ 
    std::string out; 

    if (codepoint <= 0x7f) 
     out.append(1, static_cast<char>(codepoint)); 
    else if (codepoint <= 0x7ff) 
    { 
     out.append(1, static_cast<char>(0xc0 | ((codepoint >> 6) & 0x1f))); 
     out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f))); 
    } 
    else if (codepoint <= 0xffff) 
    { 
     out.append(1, static_cast<char>(0xe0 | ((codepoint >> 12) & 0x0f))); 
     out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f))); 
     out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f))); 
    } 
    else 
    { 
     out.append(1, static_cast<char>(0xf0 | ((codepoint >> 18) & 0x07))); 
     out.append(1, static_cast<char>(0x80 | ((codepoint >> 12) & 0x3f))); 
     out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f))); 
     out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f))); 
    } 
    return out; 
} 
+0

Эй, я узнаю этот код! –

+0

Hah! Не заметил этого! Отличный код! – puelo