19 ноября 2009 г.

Задачка №3

Вот, попался тут баг один. Вернее, не баг, а подводный камень.

Что не так в этом коде?

var
Text, Data: AnsiString;
begin
// откуда-то получаем данные. Например - от GetWindowTextA
Data := ...;

// Теперь сам код
Text := 'Text ' + Data;

ShowMessage(Text);
end;

Условия: Delphi 2009 или 2010, все настройки по-умолчанию.

Указанный выше код может не работать при некоторых неочевидных условиях. Ваша задача - объяснить почему.

Подзадачка №3.5: как исправить вышеприведённый код, чтобы избавиться от проблемы?

Ответ на задачку будет выложен где-то через месяц.

Добавлено уточнение по комментариям посетителей:

GetACP = 1251, в строке Data лежит текст в 1251. Т.е. мы запускаем программу на винде с "Язык для не unicode программ" = Русский и она работает с русским текстом.

Трансформация из unicode в ANSI и наоборот не являются проблемой в этой задаче (ладно, это очень сильная подсказка, но уж больно вещь не очевидная).

Ответ.

8 комментариев :

  1. ткну в небо :)
    ShowMessage наверно юникодный в дельфи,
    если в Data будет текст не соответвующий текущей локали (или просто неанглийский) то при преобразовании Text в UTFString чего ни будь будет не так.

    ОтветитьУдалить
  2. Да там и 'Text '+Data вроде бы будет через преобразование в юникод происходить. Благодаря чему в переменной Text вполне можно получить знаки вопроса.
    P.S. В фаерфоксе набирать посты просто невозможно.

    ОтветитьУдалить
  3. Самая первая мысль - это трансформация Анси и Юникода.

    ЗЫ, а что за проблемы в ФФ при набирании поста? Не заметил.

    ОтветитьУдалить
  4. Так, кажется я упустил важное уточнение: GetACP = 1251, в строке Data лежит текст в 1251. Т.е. мы запускаем программу на винде с "Язык для не unicode программ" = Русский и она работает с русским текстом.

    При этом в коде всё ещё ЕСТЬ косяк.

    В чём он заключается?

    Подсказка: трансформация unicode <-> ANSI тут непричём. Если вам мозолит глаза ShowMessage - представьте, что там стоит сохранение строки в файл "как есть" (побайтово).

    P.S. Смотреть в отладчике не так прикольно, как попытаться сообразить самому.

    ОтветитьУдалить
  5. Этот комментарий был удален автором.

    ОтветитьУдалить
  6. Как я уже сказал, трансформация из unicode в ANSI и наоборот не являются проблемой в этой задаче (ладно, это очень сильная подсказка, но уж больно вещь не очевидная).

    ОтветитьУдалить
  7. Кста, если сообразите, в чём проблема, то подзадачка №3.5: как исправить вышеприведённый код, чтобы избавиться от проблемы?
    Я с этим почти весь день сидел :D

    ОтветитьУдалить
  8. В Text будет значение "Text ", т.е. Data не приконкатенируется. Мучился сам с этим, решил как-то... кажется, что-то типа явного приведения к типу AnsiString.

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и (опционально) ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.