powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Кодировка текста (про TEncoding читал и пробовал)
35 сообщений из 35, показаны все 2 страниц
Кодировка текста (про TEncoding читал и пробовал)
    #39145573
smallserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Долго рылся на форуме, но не нашел :(. Есть текстовый файл в кодировке 866.
Читаю оттуда строку кракозябр и нужно перевести её в WIN1251. Но у
TEncoding я не нашел нужную мне кодировку. Кто знает - помогите,
пожалуйста. Пытался так :

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure TForm1.STF(s:string);
var
msg:TStringList;
begin
msg:=TStringList.Create;
msg.Add(s);
msg.SaveToFile('dsgsd.txt', TEncoding.UTF8 ) ;
end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145581
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Яву знаешь? Если да, то проще некуда: 17506892
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145582
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С чего взяли, что UTF8 = 866? Что там цифра 8 в обоих есть? )
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145584
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smallsergЧитаю оттуда строку

Начнём с того, что приведённый код записывает строку.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145588
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmokersmallsergЧитаю оттуда строку

Начнём с того, что приведённый код записывает строку.
И добей его тем, что
smallsergДолго рылся на форуме, но не нашел
Не соответствует действительности.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145592
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
var
  Encoding866: TMBCSEncoding;
begin
  Encoding866 := TMBCSEncoding.Create(866);
  try
    // работаем с Encoding866
  finally
    FreeAndNil(Encoding866);
  end;
end;



Ну и как бы, если кодировка совсем фиксирована, то TEncoding не нужен. TEncoding применяется, когда кодировка не известна на этапе компиляции.

А так-то можно:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
type
  String866 = type AnsiString(866);

var
  Str866: String866;
  Str: String;
begin
  Str := 'Привет'; // - UTF-16 (aka Unicode)
  Str866 := Str; // - волшебство
  // Str866 - OEM 866 (aka Cyrillic MS-DOS)
end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145684
smallserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker,

Проверил последний пример - волшебства не увидел. Как были символы 'Привет',
так эти символы и записались в файл. Я же пытаюсь добиться отображения
кракозябр русскими буквами.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145689
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smallserg,

Попробуй так:

Код: pascal
1.
StringList.LoadFromFile(FileName,TEncoding.GetEncoding(866));
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145693
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smallsergПроверил последний пример - волшебства не увидел. Как были символы 'Привет',
так эти символы и записались в файл. Я же пытаюсь добиться отображения
кракозябр русскими буквами.Правильно поставленный вопрос содержит половину ответа. Вот и учись ставить. Пока у тебя не стыкуется код с вопросами, а телепатов, чтобы понять, что тебе на самом деле нужно, здесь очень мало
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145698
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DarkMasterПопробуй так:Это конвертнёт из CP-866 в UTF-16, не уверен что это надо ТС-у :)
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145742
kv67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
function ConvFromDOS(Source: String): String;
var
  i: integer;

begin
  Result := '';
  for i := 1 to Length(Source) do
    begin
      case Ord(Source[i]) of
        240: Source[i] := Chr(168);                                               //  буква Ё (большая)
        241: Source[i] := Chr(184);                                               //  буква ё (маленькая)
        252: Source[i] := Chr(185);                                               //  знак №  (номер)
          else
        if (Ord(Source[i]) > 127) then
          if Ord(Source[i]) < 176 then
            Source[i] := Chr(Ord(Source[i]) + 64)
              else
            Source[i] := Chr(Ord(Source[i]) + 16);
      end;
    end;
  Result := Source;
end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145748
kv67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Точнее, так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
function ConvFromDOS(const Source: String): String;
var
  i: integer;

begin
  Result := '';
  for i := 1 to Length(Source) do
    begin
      case Ord(Source[i]) of
        240: Source[i] := Chr(168);                                               //  буква Ё (большая)
        241: Source[i] := Chr(184);                                               //  буква ё (маленькая)
        252: Source[i] := Chr(185);                                               //  знак №  (номер)
          else
        if (Ord(Source[i]) > 127) then
          if Ord(Source[i]) < 176 then
            Source[i] := Chr(Ord(Source[i]) + 64)
              else
            Source[i] := Chr(Ord(Source[i]) + 16);
      end;
    end;
  Result := Source;
end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145764
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smallsergКак были символы 'Привет', так эти символы и записались в файл.

Несложно сообразить, что проблема - в записи в файл. Для танкистов:

Вариант с TEncoding:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
var
  Enc866: TMBCSEncoding;
  B: TBytes;
  FS: TFileStream;
begin
  Enc866 := TMBCSEncoding.Create(866);
  try
    Caption := 'Encoding: ' + IntToStr(Enc866.CodePage);
    B := Enc866.GetBytes('Привет');
  finally
    FreeAndNil(Enc866);
  end;

  FS := TFileStream.Create('My.txt', fmCreate or fmShareExclusive);
  try
    FS.WriteBuffer(Pointer(B)^, Length(B));
  finally
    FreeAndNil(FS);
  end;
end;



Вариант с AnsiString(CodePage):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
type
  String866 = type AnsiString(866);

var
  Str866: String866;
  Str: String;
  FS: TFileStream;
begin
  Str := 'Привет';
  Caption := 'Str: ' + IntToStr(StringCodePage(Str)); // - UTF-16 (aka Unicode)
  Str866 := Str; // - волшебство
  Caption := Caption + ' Str866: ' + IntToStr(StringCodePage(Str866)); // Str866 - OEM 866 (aka Cyrillic MS-DOS)

  FS := TFileStream.Create('My.txt', fmCreate or fmShareExclusive);
  try
    FS.WriteBuffer(Pointer(Str866)^, Length(Str866) * SizeOf(Str866[1]));
  finally
    FreeAndNil(FS);
  end;
end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145766
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вариант с TStringList:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
var
  Enc866: TMBCSEncoding;
  Str: TStringList;
begin
  Str := TStringList.Create;
  try
    Str.Add('Привет');

    Enc866 := TMBCSEncoding.Create(866);
    try
      Caption := 'Encoding: ' + IntToStr(Enc866.CodePage);
      Str.SaveToFile('My.txt', Enc866);
    finally
      FreeAndNil(Enc866);
    end;

  finally
    FreeAndNil(Str);
  end;
end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145876
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати...

DarkMasterПопробуй так:
Код: pascal
1.
StringList.LoadFromFile(FileName, TEncoding.GetEncoding(866));



Утечка. TEncoding.GetEncoding создаёт новый объект, который нужно освобождать.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145878
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и, соответственно, в моих примерах выше можно по аналогии TMBCSEncoding.Create(866) заменить на TEncoding.GetEncoding(866) (и TMBCSEncoding на TEncoding).
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39145911
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker,

Это как бы очевидный пример для отображения. С остальным просто не стал заморачиваться.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146102
smallserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker,

Спасибо, конечно, за помощь, но перед тем как выложить пост вы пробуете
компилировать ваши варианты? Вариант с TStringList дает ошибку "Undeckared identitfier: CodePage"
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146123
smallserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmokerВариант с TStringList:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
var
  Enc866: TMBCSEncoding;
  Str: TStringList;
begin
  Str := TStringList.Create;
  try
    Str.Add('Привет');

    Enc866 := TMBCSEncoding.Create(866);
    try
      Caption := 'Encoding: ' + IntToStr(Enc866.CodePage);
      Str.SaveToFile('My.txt', Enc866);
    finally
      FreeAndNil(Enc866);
    end;

  finally
    FreeAndNil(Str);
  end;
end;



Этот вариант действительно записывает Привет в кодировке 866. Но почему тогда не
проходит обратная перекодировка? Пробую вот так :
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
 function TForm1.ConvFromDOS(s: String): String;
var
  Enc866: TMBCSEncoding;
  Str: TStringList;
begin
  Str := TStringList.Create;
  try
    Str.Add('ЏаЁўҐв');

    Enc866 := TMBCSEncoding.Create(1251);
    try

      Str.SaveToFile('My.txt', Enc866);
    finally
      FreeAndNil(Enc866);
    end;

  finally
    FreeAndNil(Str);
  end;
end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146159
smallserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так тоже не получается

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
type
     String1251 = type AnsiString(1251);

 function TForm1.ConvFromDOS2(s: String): String;
var
  Str866: String1251;
  Str: String;
  FS: TFileStream;
begin
  Str := 'ЏаЁўҐв';
  Caption := 'Str: ' + IntToStr(StringCodePage(Str)); // - UTF-16 (aka Unicode)
  Str866 := Str; // - волшебство
  Caption := Caption + ' Str866: ' + IntToStr(StringCodePage(Str866)); // Str866 - OEM 866 (aka Cyrillic MS-DOS)

  FS := TFileStream.Create('My2.txt', fmCreate or fmShareExclusive);
  try
    FS.WriteBuffer(Pointer(Str866)^, Length(Str866) * SizeOf(Str866[1]));
  finally
    FreeAndNil(FS);
  end;
end;



естественно, type объявлен в public
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146178
smallserg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kv67Точнее, так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
function ConvFromDOS(const Source: String): String;
var
  i: integer;

begin
  Result := '';
  Source :='ЏаЁўҐв';
  for i := 1 to Length(Source) do
    begin
      case Ord(Source[i]) of
        240: Source[i] := Chr(168);                                               //  буква Ё (большая)
        241: Source[i] := Chr(184);                                               //  буква ё (маленькая)
        252: Source[i] := Chr(185);                                               //  знак №  (номер)
          else
        if (Ord(Source[i]) > 127) then
          if Ord(Source[i]) < 176 then
            Source[i] := Chr(Ord(Source[i]) + 64)
              else
            Source[i] := Chr(Ord(Source[i]) + 16);
      end;
    end;
  Result := Source;
end;



ЏаЁўҐв - это слово Привет в кодировке 866.

В результате ваша функция получила из него 'ПрБѮҠт'
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146284
jmp_original
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
smallsergЏаЁўҐв - это слово Привет в кодировке 866.
Если я всё правильно вижу™, то - нет. В вашем случае это ЏаЁўҐв в кодировке unicode.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146303
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНо почему тогда не проходит обратная перекодировка?

Поточу что нет знания о том, что такое строки и кодировки.

Строка - это текст. Например, 'привет'. Она имеет представление в байтах, которое определяет кодировка. И эти два представления смешивать не нужно. В строках нужно хранить текст и не пытаться вставлять в них "байтовое представление строки 'привет' в кодировке MS DOS".
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146311
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146653
kv67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
smallserg,

Прошу прощения, у меня работает вот так (немного поправил функцию):

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
function ConvFromDOS(Source: String): String;
var
  i: integer;

begin
  Result := '';
  for i := 1 to Length(Source) do
    begin
      case Ord(Source[i]) of
        240: Source[i] := Chr(168);                                               
        241: Source[i] := Chr(184);                                              
        252: Source[i] := Chr(185);                                               
          else
        if (Ord(Source[i]) > 127) then
          if Ord(Source[i]) < 176 then
            Source[i] := Chr(Ord(Source[i]) + 64)
              else
            Source[i] := Chr(Ord(Source[i]) + 16);
      end;
    end;
  Result := Source;
end;

procedure TfmTest.Button1Click(Sender: TObject);
begin
  ShowMessage(ConvFromDOS('ЏаЁўҐв'));
end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146672
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kv67, несложно сообразить, что раз автор вопроса говорит про TEncoding - то он использует Delphi 2009 и выше, где String = UnicodeString = двухбайтовая строка.

Соответственно, этот код (написанный в предположении Delphi 2007 и ниже, где String = AnsiString = однобайтовая строка) правильно работать не будет.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146678
kv67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker,

Согласен, у меня - Delphi 7.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146694
kv67
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker,

А если так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
function ConvFromDOS(Source: AnsiString): AnsiString;
var
  i: integer;

begin
  Result := '';
  for i := 1 to Length(Source) do
    begin
      case Ord(Source[i]) of
        240: Source[i] := AnsiChar(168);
        241: Source[i] := AnsiChar(184);
        252: Source[i] := AnsiChar(185);
          else
        if (Ord(Source[i]) > 127) then
          if Ord(Source[i]) < 176 then
            Source[i] := AnsiChar(Ord(Source[i]) + 64)
              else
            Source[i] := AnsiChar(Ord(Source[i]) + 16);
      end;
    end;
  Result := Source;
end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146833
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kv67, в D2009+ AnsiString-строки - это не просто однобайтовые буфера. Там дополнительно хранится ещё кодовая страница. Соответственно, по умолчанию в AnsiString она = CP_ACP, что на "русской Windows" = 1251. Ну и когда в такую строку пихают хрен знает что (= " не текст в 1251") - ничего хорошего из этого обычно не получается.

Для фиксированных кодовых страниц есть type AnsiString( CP ), для произвольных кодовых страниц - RawByteString (ну либо TEncoding). Для особых извращенцев есть ещё SetCodePage.

И нафиг не нужно в D2009+ выполнять какие-то преобразования руками. Достаточно понимать, что у тебя где лежит (где байты, где строки, и где какая кодировка) - и всё преобразуется простым присвоением одного к другому. Я в упор не вижу, что тут сложного/непонятного. Не надо лепить монстров - просто нажмите F1.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146855
Сергей из Самары
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А чего не сделать простым способом?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
    Procedure TForm1.BitBtn1Click(Sender: TObject);
    var OldStr,NewStr:string;
    begin
      OldStr:='+&#186;&#244;&#247;&#240; T&#248;&#244;&#248;  -&#252;&#248;&#170;&#168;&#248;&#245;&#242;&#253;&#240;';
      SetLength(NewStr, Length(OldStr));
      if OemToChar(PChar(OldStr),PChar(NewStr)) then
       showmessage(NewStr);
    end;
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146858
Сергей из Самары
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей из Самары,

Чего-то при копировании кодировка 866 слетела.
oldstr в кодировке dos
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146864
Сергей из Самары
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще правильней так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
    Procedure TForm1.BitBtn1Click(Sender: TObject);
    var OldStr:string;
    begin
      OldStr:='+&#186;&#244;&#247;&#240; T&#248;&#244;&#248;  -&#252;&#248;&#170;&#168;&#248;&#245;&#242;&#253;&#240;';
      if OemToChar(PChar(OldStr),PChar(OldStr)) then
       showmessage(OldStr);
    end;



Правда, давно уже с этой функцией работал, пишу по ппамяти, так что могу немного где-то ошибиться. Нужно проверить на проекте.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39146871
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Товарищи, вы голову совсем/принципиально не включаете? Или читать не умеете? Как можно постить код сразу после детального объяснения, почему он не будет работать?
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Кодировка текста (про TEncoding читал и пробовал)
    #39905597
yemets63
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker,

прошло почти 4 года с топика.
и число было 13-е и достаточно поздно

могу на всю петицию автора написать "НУ НУ".

Поработайте одновременно с Кириллицей, Умлаутами Немецкими и Турецкими, я посмотрю как Вы заговорите.
...
Рейтинг: 0 / 0
Кодировка текста (про TEncoding читал и пробовал)
    #39906121
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
yemets63, :facepalm:
...
Рейтинг: 0 / 0
35 сообщений из 35, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Кодировка текста (про TEncoding читал и пробовал)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]