TStringList - баг или фича ?

Проектирование и разработка идеального средства программирования.

Модератор: Модераторы

Ответить
Аватара пользователя
Alexander
энтузиаст
Сообщения: 864
Зарегистрирован: 18.12.2005 18:10:00
Откуда: оттуда
Контактная информация:

TStringList - баг или фича ?

Сообщение Alexander »

В основном не использовал классы при загрузке/сохранении, но решил попробовать.

Возник вопрос, почему TStringList сохраняет лишнюю строку. Или так он и задуман ?

Код: Выделить всё

{$MODE OBJFPC}{$H+}
uses classes;
var
  Lines: TStringList;
begin
Lines := TStringList.Create;
Lines.LoadFromFile('a.txt');
Lines.SaveToFile('b.txt');
Lines.Free;
end.
Если в файле a.txt нет ничего, то и b.txt имеет нулевую длину. Но если в a.txt добавить хоть одну латинскую букву, то в b.txt появится лишний перевод строки. Или это особенность моей версии компилятора ?
Аватара пользователя
Alexx2000
постоялец
Сообщения: 490
Зарегистрирован: 25.10.2006 00:22:07
Откуда: Мытищи
Контактная информация:

Сообщение Alexx2000 »

Вроде это особенность TStringList. Насколько я помню, данное поведение управляется свойством SkipLastLineBreak.
iskander
энтузиаст
Сообщения: 627
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

Alexx2000 писал(а):данное поведение управляется свойством SkipLastLineBreak.
Даже двумя, есть ещё TStrings.TrailingLineBreak.
Только не спрашивайте меня, зачем стринглисту целых два свойства по столь пустяковому поводу.
Аватара пользователя
Alexander
энтузиаст
Сообщения: 864
Зарегистрирован: 18.12.2005 18:10:00
Откуда: оттуда
Контактная информация:

Сообщение Alexander »

Спасибо!
xchgeaxeax
постоялец
Сообщения: 198
Зарегистрирован: 11.05.2023 02:51:40

Сообщение xchgeaxeax »

iskander писал(а):Только не спрашивайте меня, зачем стринглисту целых два свойства по столь пустяковому поводу.

Код: Выделить всё

    // Same as SkipLastLineBreak but for Delphi compatibility. Note it has opposite meaning.
    Property TrailingLineBreak : Boolean Read GetTrailingLineBreak Write SetTrailingLineBreak;
По поводу этого второго свойства есть комментарий.
iskander
энтузиаст
Сообщения: 627
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

Можно ещё

Код: Выделить всё

  StringList.Options := StringList.Options - [soTrailingLineBreak];
xchgeaxeax писал(а):По поводу этого второго свойства есть комментарий.
Идиотизм с комментарием лучше чем без комментария?
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

iskander писал(а):Идиотизм с комментарием лучше чем без комментария?
"Всё то вздор, чего не знает наш Митрофанушка!" (С)
Аватара пользователя
Alexander
энтузиаст
Сообщения: 864
Зарегистрирован: 18.12.2005 18:10:00
Откуда: оттуда
Контактная информация:

Сообщение Alexander »

Я бы сказал, что поведение по умолчанию удивляет. Лучше бы сделали наоборот: сразу сохраняет привычным способом, а кому нужно необычное - включает его. Как-то по логике: если мы загрузили файл и потом его же сохранили он должен оставаться неизменным, а всё остальное специальный случай.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

Поведение стринглиста связано с механизмом разбиения текста на отдельные строки. А кто гонится за неизменностью должен использовать бинарный формат данных.
v-t-l
энтузиаст
Сообщения: 744
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение v-t-l »

Alexander писал(а):Я бы сказал, что поведение по умолчанию удивляет.
Так издревле вел себя TStringList в Delphi.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

Не могу понять претензий - если помнить, что задача стринглиста - представлять текст в виде массива строк, а признак конца строки - LineBreak, то поведение компонента совершенно логично. Если кто-то считает, что последняя строка не должна иметь признака конца, то это его личные проблемы.
Аватара пользователя
Alexander
энтузиаст
Сообщения: 864
Зарегистрирован: 18.12.2005 18:10:00
Откуда: оттуда
Контактная информация:

Сообщение Alexander »

Возьмём файл t.txt Без переноса после "c".

И применим два способа посчитать количество строк в файле из Интернета.

Код: Выделить всё

wc -l t.txt

Код: Выделить всё

awk 'END{print NR}' t.txt
Результат удивит.
Так что как считать: вопрос не такой простой, а до сих пор спорный. Очевидно, что в файле 3 строки, но wc выдаст 2, а awk 3.

Добавлено спустя 59 минут 22 секунды:
Когда EOF исчез из файлов и возник этот спор ведь тогда такой файл это последовательность 'a'#10'b'#10'c'#26, а до этого и спора не могло возникнуть. Замечу дополнительно, что среди строк есть такая строка, как пустая. Тогда 'a'#10'b'#10'c'#10#26 её бы и предполагал в качестве последней.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

Претензии к wc в ваших линухах. Впрочем, в русской инструкции написано прямо, что строки она считает по числу символов перевода строки. Хотите получать правильный разбор на строки - правильно формируйте текстовый файл.
Ответить