Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Чтение строк в TStringList в полях которых есть перевод строки / 12 сообщений из 12, страница 1 из 1
23.02.2021, 14:27
    #40048136
hlopotun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
Всем доброго дня,

есть csv со строками, примерно такого вида:

"Field1";"Field2";"Field3";"Field4"
"123";"345
577
789";"abcd";"ttttt"
"654";"555";"aaaa";"bbbb"

в некоторых полях встречается перевод строки.
Читаю так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
 CsvStr := TStringList.Create;
     CsvStr.StrictDelimiter := True; // на случай если не будет QuotedChar (но в даннон случае он есть)
     CsvStr.Delimiter := ';';
     CsvStr.QuoteChar := '"';
     CsvStr.LineBreak := '"'+sLineBreak;

CsvStr.DelimitedText := sStr; // с содержимым файла


всёравно разбивка на строки происходит по переводу строки.
Всё уже перепробовал, не пойму где ошибаюсь.
Посоветуйте чтото.

Спасибо.
...
Рейтинг: 0 / 0
23.02.2021, 14:32
    #40048138
Cobalt747
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
Рекомендую пройти отладкой по методу TStrings.SetDelimitedText - там вы все увидите сами
...
Рейтинг: 0 / 0
23.02.2021, 15:00
    #40048144
DHDD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
...
Рейтинг: 0 / 0
23.02.2021, 15:05
    #40048150
hlopotun
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
Cobalt747,

странно, LineBreak в коде даже не упоминается ...

Код: 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.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
procedure TStrings.SetDelimitedText(const Value: string);
var
  P, P1: PChar;
  S: string;
begin
  BeginUpdate;
  try
    Clear;
    P := PChar(Value);
    if not StrictDelimiter then
      while (P^ in [#1..' ']) do
        P := NextChar(P);
    while P^ <> #0 do
    begin
      if (P^ = QuoteChar) and (QuoteChar <> #0) then
        S := AnsiExtractQuotedStr(P, QuoteChar)
      else
      begin
        P1 := P;
        while ((not StrictDelimiter and (P^ > ' ')) or
              (StrictDelimiter and (P^ <> #0))) and (P^ <> Delimiter) do
          P := NextChar(P);
        SetString(S, P1, P - P1);
      end;
      Add(S);
      if not StrictDelimiter then
        while (P^ in [#1..' ']) do
          P := NextChar(P);

      if P^ = Delimiter then
      begin
        P1 := P;
        if NextChar(P1)^ = #0 then
          Add('');
        repeat
          P := NextChar(P);
        until not (not StrictDelimiter and (P^ in [#1..' ']));
      end;
    end;
  finally
    EndUpdate;
  end;
end;



значит это что DelimetedText даже нет смысла использовать.
Я тут пример немного упростил, на самом деле читается через LoadFromFile,
а он судя по исходнику использует SetTextStr в котором LineBreak уже присутствует:

procedure TStrings.LoadFromFile(const FileName: string);
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromStream(Stream);
finally
Stream.Free;
end;
end;

procedure TStrings.LoadFromStream(Stream: TStream);
begin
LoadFromStream(Stream, nil);
end;

procedure TStrings.LoadFromStream(Stream: TStream; Encoding: TEncoding);
var
Size: Integer;
Buffer: TBytes;
begin
BeginUpdate;
try
Size := Stream.Size - Stream.Position;
SetLength(Buffer, Size);
Stream.Read(Buffer, 0, Size);
Size := TEncoding.GetBufferEncoding(Buffer, Encoding, FDefaultEncoding);
SetEncoding(Encoding); // Keep Encoding in case the stream is saved
SetTextStr(Encoding.GetString(Buffer, Size, Length(Buffer) - Size));
finally
EndUpdate;
end;
end;

procedure TStrings.SetTextStr(const Value: string);
var
P, PCurVal, PCurLB, PStartVal, PStartLB, PEndLB: PChar;
S: string;
LineBreakLen: Integer;
begin
BeginUpdate;
try
Clear;
P := Pointer(Value);
if P = nil then
Exit;

LineBreakLen := Length(LineBreak);
if LineBreakLen = 0 then
begin
Add(Value);
Exit;
end;

// When LineBreak is:
// * sLineBreak - for compatibility with Windows, Posix and old macOS platforms,
// we handle #13#10, #10 and #13 as it would be #13#10.
// * NOT sLineBreak - we use strict checking for LineBreak.
if CompareStr(LineBreak, sLineBreak) = 0 then
begin
while P^ <> #0 do
begin
PStartVal := P;
while not (P^ in [#0, #10, #13]) do Inc(P);
SetString(S, PStartVal, P - PStartVal);
Add(S);
if P^ = #13 then Inc(P);
if P^ = #10 then Inc(P);
end;
Exit;
end;

PStartLB := Pointer(LineBreak);
PEndLB := PStartLB + LineBreakLen;
PCurLB := PStartLB;
PStartVal := P;

while P^ <> #0 do
begin
while (P^ <> PStartLB^) and (P^ <> #0) do
Inc(P);
if P^ <> #0 then
begin
PCurVal := P + 1;
Inc(PCurLB);
while PCurLB^ <> #0 do
begin
if PCurVal^ <> PCurLB^ then
Break;
Inc(PCurVal);
Inc(PCurLB)
end;
if PCurLB = PEndLB then
begin
SetString(S, PStartVal, P - PStartVal);
Add(S);
P := PCurVal;
PStartVal := P;
end
else
Inc(P);
PCurLB := PStartLB;
end;
end;

if P > PStartVal then
begin
SetString(S, PStartVal, P - PStartVal);
Add(S);
end;
finally
EndUpdate;
end;
end;
...
Рейтинг: 0 / 0
23.02.2021, 16:33
    #40048180
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
сделать замену в sStr #13#10 на какую-то подстроку вида '{#13#10}'
а потом пробежаться по итемсам и поменять назад

будет помедленнее (
...
Рейтинг: 0 / 0
23.02.2021, 16:53
    #40048183
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
Какой только фигнёй люди не будут маяться место написания простенького автомата на пару
экранов...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
23.02.2021, 16:56
    #40048185
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
Dimitry Sibiryakov
на пару экранов...
Или я чего-то не понимаю, или тут максимум строчек 20
...
Рейтинг: 0 / 0
23.02.2021, 17:04
    #40048186
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
_Vasilisk_
Dimitry Sibiryakov
на пару экранов...
Или я чего-то не понимаю, или тут максимум строчек 20
кавычки ещё пощитать же
...
Рейтинг: 0 / 0
23.02.2021, 17:20
    #40048191
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
andreymx
кавычки ещё пощитать же
Без кавычек Можно уложиться в одну строку
Код: pascal
1.
string.Split([';'])

+ 5 строк на цикл чтения файла
...
Рейтинг: 0 / 0
23.02.2021, 17:37
    #40048193
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
_Vasilisk_
andreymx
кавычки ещё пощитать же
Без кавычек Можно уложиться в одну строку
Код: pascal
1.
string.Split([';'])


+ 5 строк на цикл чтения файла
это из более нового, чем мой древний д7?
...
Рейтинг: 0 / 0
23.02.2021, 17:41
    #40048194
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
andreymx
это из более нового, чем мой древний д7?
Да XE3 (а может и раньше) и новее
...
Рейтинг: 0 / 0
23.02.2021, 17:44
    #40048195
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение строк в TStringList в полях которых есть перевод строки
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Чтение строк в TStringList в полях которых есть перевод строки / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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