В VC ++ 2003, я мог просто сохранить исходный файл как UTF-8, и все строки были использованы как есть. Другими словами, следующий код распечатал бы строки, как к консоли. Если бы исходный файл был сохранен как UTF-8 затем, то вывод был бы UTF-8.
printf("Chinese (Traditional)");
printf("中国語 (繁体)");
printf("중국어 (번체)");
printf("Chinês (Tradicional)");
Я сохранил файл в формате UTF-8 с BOM UTF-8. Однако компиляция с VC2008 приводит к:
warning C4566: character represented by universal-character-name '\uC911'
cannot be represented in the current code page (932)
warning C4566: character represented by universal-character-name '\uAD6D'
cannot be represented in the current code page (932)
etc.
Символы, вызывающие эти предупреждения, повреждаются. Те, которые действительно соответствуют локали (в этом случае 932 = японский язык) преобразовываются в кодирование локали, т.е. Shift JIS.
Я не могу найти способ заставить VC ++ 2008 компилировать это для меня. Обратите внимание, что не имеет значения, какую локаль я использую в исходном файле. Кажется, нет локали, которая говорит, что "Я знаю то, что я делаю, не делайте % f$ ##ng изменяет мои строковые литералы". В частности, бесполезная псевдолокаль UTF-8 не работает.
#pragma setlocale(".65001")
=> error C2175: '.65001' : invalid locale
Ни один не делает "C":
#pragma setlocale("C")
=> see warnings above (in particular locale is still 932)
Кажется, что VC2008 вызывает все символы в указанное (или значение по умолчанию) локаль, и что локаль не может быть UTF-8. Я не хочу изменять файл для использования строк Escape как "\xbf\x11...", потому что тот же источник компилируется с помощью gcc, который может вполне счастливо иметь дело с файлами UTF-8.
Там какой-либо путь состоит в том, чтобы указать, что компиляция исходного файла должна оставить строковые литералы нетронутыми?
Для выяснения у этого по-другому какие флаги компиляции могут, я использую для определения обратной совместимости с VC2003 при компиляции исходного файла. т.е. не изменяйте строковые литералы, используйте их байт для байта как они.
Обновление
Спасибо за предложения, но я хочу избежать wchar. Начиная с этого приложения соглашения со строками в UTF-8 исключительно, с помощью wchar затем потребовали бы, чтобы я преобразовал все строки назад в UTF-8, который должен быть ненужным. Весь вход, вывод и внутренняя обработка находятся в UTF-8. Это - простое приложение, которое хорошо работает, как находится на Linux и при компиляции с VC2003. Я хочу смочь скомпилировать то же приложение с VC2008 и иметь его работа.
Чтобы это произошло, мне нужен VC2008, чтобы не попытаться преобразовать его в локаль моей локальной машины (японский язык, 932). Я хочу, чтобы VC2008 был обратно совместим с VC2003. Я хочу локаль или параметр компилятора, который говорит, что строки использованы как есть, по существу как непрозрачные массивы символа, или как UTF-8. Похоже, что я мог бы застрять с VC2003 и gcc, хотя, VC2008 пытается быть слишком умным в этом экземпляре.
Обновление:
Я решил, что нет никакого гарантируемого способа сделать это. Решение, которое я представляю ниже работ для английской версии VC2003, но сбои при компиляции с японской версией VC2003 (или возможно это - японская ОС). В любом случае это не может зависеться от работать. Обратите внимание, что, даже объявляя все как L"" строки не работало (и является болезненным в gcc, как описано ниже).
Вместо этого я полагаю, что просто необходимо стиснуть зубы и переместить весь текст в файл данных и загрузить его оттуда. Я теперь храню и получаю доступ к тексту в файлах INI через SimpleIni (межплатформенная библиотека INI-файла). По крайней мере, существует гарантия, что это работает, как весь текст вне программы.
Исходный:
Я отвечаю на это сам с тех пор, только Evan, казалось, понял проблему. Ответы относительно того, что Unicode и как использовать wchar_t, не важны для этой проблемы, поскольку это не об интернационализации, ни неверном толковании Unicode, кодировок символов. Я ценю Вашу попытку помочь, хотя, извинения, если я не был достаточно ясен.
Проблема состоит в том, что у меня есть исходные файлы, которые должны быть кросс-скомпилированы под множеством платформ и компиляторов. Программа делает обработку UTF-8. Это не заботится ни о какой другой кодировке. Я хочу иметь строковые литералы в UTF-8 как в настоящее время работы с gcc и vc2003. Как я делаю это с VC2008? (т.е. обратно совместимое решение).
Это - то, что я нашел:
gcc (v4.3.2 20081105):
vc2003:
vc2005 +:
Так, простой ответ - то, что для этой конкретной цели, VC2005 + повреждается и не предоставляет обратно совместимый путь компиляции. Единственный способ получить строки Unicode в скомпилированную программу через UTF-8 + BOM + wchar, что означает, что я должен преобразовать все строки назад в UTF-8 во время использования.
Нет никакого простого межплатформенного метода преобразования wchar к UTF-8, например, в чем размер и кодирование являются wchar? В Windows, UTF-16. На других платформах? Это варьируется. См. проект ICU для некоторых деталей.
В конце я решил, что избегу стоимости преобразования на всех компиляторах кроме vc2005 + с источником как следующее.
#if defined(_MSC_VER) && _MSC_VER > 1310
// Visual C++ 2005 and later require the source files in UTF-8, and all strings
// to be encoded as wchar_t otherwise the strings will be converted into the
// local multibyte encoding and cause errors. To use a wchar_t as UTF-8, these
// strings then need to be convert back to UTF-8. This function is just a rough
// example of how to do this.
# define utf8(str) ConvertToUTF8(L##str)
const char * ConvertToUTF8(const wchar_t * pStr) {
static char szBuf[1024];
WideCharToMultiByte(CP_UTF8, 0, pStr, -1, szBuf, sizeof(szBuf), NULL, NULL);
return szBuf;
}
#else
// Visual C++ 2003 and gcc will use the string literals as is, so the files
// should be saved as UTF-8. gcc requires the files to not have a UTF-8 BOM.
# define utf8(str) str
#endif
Обратите внимание, что этот код является просто упрощенным примером. Производственное использование должно было бы очистить его во множестве путей (потокобезопасность, проверка ошибок, проверки размера буфера, и т.д.).
Это используется как следующий код. Это компилирует чисто и работает правильно в моих тестах на gcc, vc2003, и vc2008:
std::string mText;
mText = utf8("Chinese (Traditional)");
mText = utf8("中国語 (繁体)");
mText = utf8("중국어 (번체)");
mText = utf8("Chinês (Tradicional)");
Эти два шестнадцатеричных числа в
Not a JPEG file: starts with 0x48 0x54
переведите в ASCII HT
то, которое я предполагаю, продолжает HTTP[...]
. Проверьте заголовок файла с xxd -l 20 img.jpg
. Это должно ожидаться вывод от последней команды, которую Вы отправили с тех пор
wget --save-headers
сообщает wget
предварительно ожидать вывод с HTTP
заголовок ответа.
Два других вызова не сделают этого.
curl
или wget
. Для wget
загружать файл, пользовательскую строку -U
необходим, иначе сервер отказывается. Любое использование curl -o img.jpg $1
или
wget -U "Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.17 (KHTML, Gecko) Ubuntu/11.04 Chromium/11.0.654.0 Chrome/11.0.654.0 Safari/534.17" $1 -O img.jpg
без --save-headers
.
Прочитайте статьи. Во-первых, Вы не хотите UTF-8. UTF-8 является только способом представить символы. Вы хотите широкие символы (wchar_t). Вы записываете их как L "yourtextgoeshere". Тип того литерала является wchar_t*. Если Вы спешите, просто ищете wprintf.
Необходимо Загрузить Драйвер с веб-сайта Брата
, Чтобы проверить, выполняете ли Вы рабочие 32 бита или 64 бита этот Результат команды
uname -a
для 32-разрядной Ubuntu:
Linux discworld 2.6.38-8-универсальный # SMP с 42 Ubuntu понедельник 11 апреля 3:31:50 UTC 2011 GNU/Linux i686 i686 i386
, тогда как 64-разрядная Ubuntu покажет:
Linux discworld 2.6.38-8-универсальный # SMP с 42 Ubuntu понедельник 11 апреля 3:31:50 UTC 2011 GNU/Linux x86_64 x86_64 x86_64 , если Вы выполняете версию на 32 бита Ubuntu.
выполняет эти команды, если Вы находитесь на 32 битах
wget http://download.brother.com/welcome/dlf100975/libsane-dsseries_1.0.5-1_i386.deb
sudo dpkg -i --force-all libsane-dsseries_1.0.5-1_i386.deb
при выполнении выполнения на 64 бита эти команды.
wget http://download.brother.com/welcome/dlf100976/libsane-dsseries_1.0.5-1_amd64.deb
sudo dpkg -i --force-all libsane-dsseries_1.0.5-1_amd64.deb
Я не уверен, что Вы спрашиваете, но Вы могли сделать что-то вроде этого:
Скажем, Вы находитесь в каталоге, в котором у Вас есть папки folder1 и файлы A, B и A123, A456, A789.
можно переместить файл с помощью команды:
mv A folder1
Это перемещает файл A в folder1
mv A* folder1
, Это перемещает файлы A123, A456 и A789 в folder1.
, Если Вы хотите переместить те файлы в подпапку folder1, скажем, subfolder1, просто сделайте:
mv A* folder1/subfolder1
Можно запустить скрипт с bash -x
для наблюдения точно, что он делает. Я заметил, что это сравнивало "expr 2 - 1", чтобы видеть, было ли это равно 0, который выглядел неправильным. Я думаю, что эта строка является неправильной:
c='expr $c - 1"
кавычки не соответствуют, таким образом, я первоначально предложил использовать двойные кавычки, но что Вы хотите, должен присвоиться результат из выполнения expr и тому подобное к c
переменная, таким образом, Вам нужны обратные галочки:
c=`expr $c - 1`
при фиксации этого и верхнего регистра If
близость начало сценарий, кажется, работает правильно.
Documentation/admin-guide/kernel-parameters.txt
(старое местоположение Documentation/kernel-parameters.txt
), сами, но я didn' t видят что-либо очевидное там.
– Doug Smythies
22 January 2017 в 07:14
У меня была подобная проблема при компиляции UTF-8 узкие (символьные) строковые литералы и что я обнаружил, в основном, у меня должен был быть и BOM UTF-8 и #pragma execution_character_set("utf-8")
[1], или ни BOM, ни прагма [2]. Используя одного без другого привел к неправильному преобразованию.
я зарегистрировал детали в https://github.com/jay/compiler_string_test
[1]: Visual Studio 2012 не поддерживает execution_character_set. 2010 и 2015 Visual Studio это хорошо работает, и поскольку Вы знаете с патчем в 2008, что это хорошо работает.
[2]: Некоторые комментарии в этом потоке отметили, что использование ни BOM, ни прагма может привести к неправильному преобразованию для разработчиков, использующих локальную кодовую страницу, которая является многобайтовой (например, Япония).
Исходные файлы UTF-8
единственное портативное устройство и компилятор независимый путь состоит в том, чтобы использовать набор символов ASCII и escape-последовательности, потому что нет никаких гарантий, что любой компилятор признал бы, что UTF-8 закодировал файл.
Так, вещи, которые будут изменены. Теперь я получил решение.
, В первую очередь, Вы должны, работая в соответствии с Единственной Локальной Кодовой страницей Байта, такой как английский язык, так, чтобы cl.exe не был, получая коды добраться, чтобы быть хаосом.
115-секундный, сохраните исходный код в UTF8-НИКАКОМ BOM, заметьте, без BOM, и затем скомпилируйте с cl.exe, СДЕЛАЙТЕ не вызов любого API C, такой как, printf wprint, все те сотрудники, не работающие, я не знаю почему:).... может иметь исследование позже...
Затем просто компиляция и выполнение, Вы будете видеть результат..... моя электронная почта является luoyonggang, надеждой (Google) на некоторых......
wscript:
#! /usr/bin/env python
# encoding: utf-8
# Yonggang Luo
# the following two variables are used by the target "waf dist"
VERSION='0.0.1'
APPNAME='cc_test'
top = '.'
import waflib.Configure
def options(opt):
opt.load('compiler_c')
def configure(conf):
conf.load('compiler_c')
conf.check_lib_msvc('gdi32')
conf.check_libs_msvc('kernel32 user32')
def build(bld):
bld.program(
features = 'c',
source = 'chinese-utf8-no-bom.c',
includes = '. ..',
cflags = ['/wd4819'],
target = 'myprogram',
use = 'KERNEL32 USER32 GDI32')
Под управлением сценарий исходный код run.bat
rd /s /q build
waf configure build --msvc_version "msvc 6.0"
build\myprogram
rd /s /q build
waf configure build --msvc_version "msvc 9.0"
build\myprogram
rd /s /q build
waf configure build --msvc_version "msvc 10.0"
build\myprogram
main.c:
//encoding : utf8 no-bom
#include <stdio.h>
#include <string.h>
#include <Windows.h>
char* ConvertFromUtf16ToUtf8(const wchar_t *wstr)
{
int requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, 0, 0, 0, 0);
if(requiredSize > 0)
{
char *buffer = malloc(requiredSize + 1);
buffer[requiredSize] = 0;
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, buffer, requiredSize, 0, 0);
return buffer;
}
return NULL;
}
wchar_t* ConvertFromUtf8ToUtf16(const char *cstr)
{
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, cstr, -1, 0, 0);
if(requiredSize > 0)
{
wchar_t *buffer = malloc( (requiredSize + 1) * sizeof(wchar_t) );
printf("converted size is %d 0x%x\n", requiredSize, buffer);
buffer[requiredSize] = 0;
MultiByteToWideChar(CP_UTF8, 0, cstr, -1, buffer, requiredSize);
printf("Finished\n");
return buffer;
}
printf("Convert failed\n");
return NULL;
}
void ShowUtf8LiteralString(char const *name, char const *str)
{
int i = 0;
wchar_t *name_w = ConvertFromUtf8ToUtf16(name);
wchar_t *str_w = ConvertFromUtf8ToUtf16(str);
printf("UTF8 sequence\n");
for (i = 0; i < strlen(str); ++i)
{
printf("%02x ", (unsigned char)str[i]);
}
printf("\nUTF16 sequence\n");
for (i = 0; i < wcslen(str_w); ++i)
{
printf("%04x ", str_w[i]);
}
//Why not using printf or wprintf? Just because they do not working:)
MessageBoxW(NULL, str_w, name_w, MB_OK);
free(name_w);
free(str_w);
}
int main()
{
ShowUtf8LiteralString("English english_c", "Chinese (Traditional)");
ShowUtf8LiteralString("简体 s_chinese_c", "你好世界");
ShowUtf8LiteralString("繁体 t_chinese_c", "中国語 (繁体)");
ShowUtf8LiteralString("Korea korea_c", "중국어 (번체)");
ShowUtf8LiteralString("What? what_c", "Chinês (Tradicional)");
}
Я знаю, что опаздываю в сторону, но я думаю, что я должен к распространить это . Для Visual C++ 2005 и выше, если исходный файл doesn’t содержит BOM (метка порядка байтов), и Ваша системная локаль не является английской, VC предположит, что Ваш исходный файл не находится в Unicode.
, Чтобы скомпилировать Ваши исходные файлы UTF-8 правильно, Вы должны сохранять в UTF-8 без кодирования BOM, и , системная локаль (язык не-Unicode) должна быть английская .
У меня была подобная проблема. Мои строковые литералы UTF-8 были преобразованы в кодовую страницу существующей системы во время компиляции - я просто открыл .obj файлы в шестнадцатеричном средстве просмотра, и они были уже искажены. Например, символ Д ‡ был всего один байт.
решение для меня состояло в том, чтобы сохранить в UTF-8 и БЕЗ BOM. Это - то, как я обманул компилятор. Это теперь думает, что это - просто нормальный источник и не переводит строки. В .obj файлах Д ‡ - теперь два байта.
Игнорирование некоторые комментаторы. Я понимаю то, что Вы хотите - я хочу то же также: источник UTF-8, UTF-8 генерировал файлы, входные файлы UTF-8, UTF-8 по линиям связи без когда-либо перевода.
, Возможно, это помогает...
Возможно, попробуйте эксперимент:
#pragma setlocale(".UTF-8")
или:
#pragma setlocale("english_england.UTF-8")
Портативное преобразование от любого собственного компонента, кодирующего Вас, имеет, простое использование char_traits:: расширитесь ().
#include <locale>
#include <string>
#include <vector>
/////////////////////////////////////////////////////////
// NativeToUtf16 - Convert a string from the native
// encoding to Unicode UTF-16
// Parameters:
// sNative (in): Input String
// Returns: Converted string
/////////////////////////////////////////////////////////
std::wstring NativeToUtf16(const std::string &sNative)
{
std::locale locNative;
// The UTF-16 will never be longer than the input string
std::vector<wchar_t> vUtf16(1+sNative.length());
// convert
std::use_facet< std::ctype<wchar_t> >(locNative).widen(
sNative.c_str(),
sNative.c_str()+sNative.length(),
&vUtf16[0]);
return std::wstring(vUtf16.begin(), vUtf16.end());
}
В теории, поездка обратно, от UTF-16 до UTF-8 должна быть столь же легкой, но я нашел, что локали UTF-8 не работают правильно над моей системой (Экспресс VC10 на Win7).
Таким образом я записал простой преобразователь на основе RFC 3629.
/////////////////////////////////////////////////////////
// Utf16ToUtf8 - Convert a character from UTF-16
// encoding to UTF-8.
// NB: Does not handle Surrogate pairs.
// Does not test for badly formed
// UTF-16
// Parameters:
// chUtf16 (in): Input char
// Returns: UTF-8 version as a string
/////////////////////////////////////////////////////////
std::string Utf16ToUtf8(wchar_t chUtf16)
{
// From RFC 3629
// 0000 0000-0000 007F 0xxxxxxx
// 0000 0080-0000 07FF 110xxxxx 10xxxxxx
// 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
// max output length is 3 bytes (plus one for Nul)
unsigned char szUtf8[4] = "";
if (chUtf16 < 0x80)
{
szUtf8[0] = static_cast<unsigned char>(chUtf16);
}
else if (chUtf16 < 0x7FF)
{
szUtf8[0] = static_cast<unsigned char>(0xC0 | ((chUtf16>>6)&0x1F));
szUtf8[1] = static_cast<unsigned char>(0x80 | (chUtf16&0x3F));
}
else
{
szUtf8[0] = static_cast<unsigned char>(0xE0 | ((chUtf16>>12)&0xF));
szUtf8[1] = static_cast<unsigned char>(0x80 | ((chUtf16>>6)&0x3F));
szUtf8[2] = static_cast<unsigned char>(0x80 | (chUtf16&0x3F));
}
return reinterpret_cast<char *>(szUtf8);
}
/////////////////////////////////////////////////////////
// Utf16ToUtf8 - Convert a string from UTF-16 encoding
// to UTF-8
// Parameters:
// sNative (in): Input String
// Returns: Converted string
/////////////////////////////////////////////////////////
std::string Utf16ToUtf8(const std::wstring &sUtf16)
{
std::string sUtf8;
std::wstring::const_iterator itr;
for (itr=sUtf16.begin(); itr!=sUtf16.end(); ++itr)
sUtf8 += Utf16ToUtf8(*itr);
return sUtf8;
}
, я полагаю, что это должно работать над любой платформой, но я не смог протестировать его за исключением своей собственной системы, таким образом, это может иметь ошибки.
#include <iostream>
#include <fstream>
int main()
{
const char szTest[] = "Das tausendschöne Jungfräulein,\n"
"Das tausendschöne Herzelein,\n"
"Wollte Gott, wollte Gott,\n"
"ich wär' heute bei ihr!\n";
std::wstring sUtf16 = NativeToUtf16(szTest);
std::string sUtf8 = Utf16ToUtf8(sUtf16);
std::ofstream ofs("test.txt");
if (ofs)
ofs << sUtf8;
return 0;
}
От комментария до этого очень хорошего блога
"Используя UTF-8 как внутреннее представление для строк в C и C++ с Visual Studio"
=> http://www.nubaria.com/en/blog/?p=289
#pragma execution_character_set("utf-8")
Это требует Visual Studio 2008 SP1 и следующих текущих исправлений:
Visual C++ (2005 +) поведение стандарта КОМПИЛЯТОРА для исходных файлов:
"Ä"
в †’ C4 00
'Ä'
в †’ C4
L"Ä"
в †’ 00C4 0000
L'Ä'
в †’ 00C4
"Ä"
в †’ C3 84 00
(= UTF-8) 'Ä'
в †’ предупреждение: мультисимвольная константа "Ω"
в †’ E2 84 A6 00
(= UTF-8, как ожидалось) L"A"
в †’ 00C3 0084 0000
(неправильно!) L'Ä'
в †’ предупреждение: мультисимвольная константа L"Ω"
в †’ 00E2 0084 00A6 0000
(неправильно!) "Ä"
в †’ C4 00
(= CP1252, больше никакого UTF-8), 'Ä'
в †’ C4
"Ω"
в †’ ошибка: не может преобразовать в CP1252! L"Ä"
в †’ 00C4 0000
(корректный) L'Ä'
в †’ 00C4
L"Ω"
в †’ 2126 0000
(корректный) Вы видите, компилятор C обрабатывает файлы UTF-8 без BOM тот же путь как CP1252. В результате для компилятора невозможно смешать UTF-8 и строки UTF-16 в скомпилированный вывод! Таким образом, необходимо решить для одного файла исходного кода:
L
префикс), L
префикс). Независимо, РЕДАКТОР может автоматически обнаружить файлы UTF-8 без BOM как файлы UTF-8.
Регистрируйте/Совершенствуйте Сохраняют Опции/Кодирование: "Unicode (UTF-8 без подписи ) - Кодовая страница 65001"
Брофилд,
я имел ту же самую проблему и просто наткнулся на решение, которое не требует преобразования Ваших исходных строк к широким символам и назад: сохраните свой исходный файл как UTF-8 без , подпись и VC2008 оставят его в покое. Работавший отлично, когда я выяснил для отбрасывания подписи.Подводя итоги:
Unicode (UTF-8 без подписи) - Кодовая страница 65001, не бросает предупреждение c4566 в VC2008 и не заставляет VC смешивать с кодированием, в то время как Кодовая страница 65001 (UTF-8 С Подписью) действительно бросает c4566 (поскольку Вы нашли).
Hope это не слишком поздно для помощи Вам, но это могло бы ускорить Ваше приложение VC2008 для удаления обходного решения.
Как насчет этого? Вы храните строки в закодированном файле UTF-8 и затем предварительно обработайте их в закодированный исходный файл C++ ASCII. Вы сохраняете кодировку UTF-8 в строке при помощи шестнадцатеричных Escape. Строка
"中国語 (繁体)"
преобразовывается в
"\xE4\xB8\xAD\xE5\x9B\xBD\xE8\xAA\x9E (\xE7\xB9\x81\xE4\xBD\x93)"
, Конечно, это нечитабельно любым человеком, и цель состоит в том, чтобы только избежать проблем с компилятором.
Вы могли или использовать препроцессор C++ для ссылки на строки в преобразованном заголовочном файле, или Вы могли преобразовать Вас весь источник UTF-8 в ASCII перед компиляцией с помощью этого приема.