Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 878

/ вопрос открыт /

Доброго времени суток, уважаемые эксперты!

Как из текстового файла с множеством строк, заполнить массив так, чтобы каждая строка была отдельный массив из нескольких значений. И вывести информацию в Мемо, для дальнейшего использования.Причем в текстовом файле значения разделенны Табуляцией.
Заранее огромное спасибо. Файл с текстом прилогаю.

К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)

Felixx Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Felixx (статус: Посетитель)
Вопрос отправлен: 5 сентября 2008, 17:30
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, Felixx!
Я покажу, как разбить одну строку, а как разбить весь файл - попробуйте догадаться самостоятельно, это очень просто, если использовать TStringList (он как Memo, только не визульный)

var s:string;//одна строка с исходного файла для разбития
     dl:TStringList;
begin
  dl:=TStringList.create;
  try
   dl.delimeter := #9;//код табуляции.
   dl.delimetertext := s;
   //всё, можно пользоваться результатами. например
   //сколко всего элементов нашло
   dl.count
   //Что там храниться в 3 позиции
   dl[2];//незабываем, что счёт с 0 и всё в виде строк. причем кавычки вокруг строк тоже будут убираться
 finally
   dl.free;
 end;
end;

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 5 сентября 2008, 17:58
Оценка за ответ: 5


Мини-форум вопроса

Всего сообщений: 19; последнее сообщение — 6 сентября 2008, 16:29; участников в обсуждении: 3.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 5 сентября 2008, 19:37 [#1]:

как объявить массив зависит от того - одинаковое ли количество элементов подразумевается в строках. И еще уточняющий вопрос - что именно и в каком виде Вы хотите выводить в memo?
Felixx

Felixx (статус: Посетитель), 5 сентября 2008, 19:44 [#2]:

Если конкретно, то я пытаюсь из этого файла сделать SQL запрос...
Сделал следующее:
В одно мемо загружаю весь файл
потом по нажатию кнопки выполняю..
procedure TForm1.Button4Click(Sender: TObject);
var
s:string;//одна строка с исходного файла для разбития
dl:TStringList;
i:integer;
begin

for i:=0 to Memo2.Lines.Count-1 do
begin
s:= Memo2.Lines[0+i];
dl:=TStringList.create;
try
dl.Delimiter:=#9;
dl.DelimitedText:=s;
memo1.Text:=(Memo1.Text+'INSERT INTO `recitems` VALUES');
memo1.Text:=(Memo1.Text+'('+dl[1]+','+dl[2]+','+dl[8]+','+'0'+');'+#13);
finally
dl.free;
end;
end;
end;

Получаются множество запросов в мемо.. и сохраняю в файл.

Но там получается не корректный переход на новую строку после каждого запроса. Подскажите как сделать корректно переход?
Вадим К

Вадим К (статус: Академик), 5 сентября 2008, 19:52 [#3]:

ну зачем писать так хитро
memo1.Text:=(Memo1.Text+'('+dl[1]+','+dl[2]+','+dl[8]+','+'0'+');'+#13);
во первых, надо знать, что под виндовсом перевод строки - это #13#10.
Но лучше писать так.
var s:string;
begin
...
if dl.count < 9 then ShowMessage('ЧП мирового масштаба, либо просто плохой файл')
else begin
s:='INSERT INTO `recitems` VALUES' +
'('+dl[1]+','+dl[2]+','+dl[8]+','+'0'+');');
Memo1.lines.add(s);
end;
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 5 сентября 2008, 19:57 [#4]:

Думаю, что лучше сделать следующим образом:
перед циклом выполнить: memo1.lines.clear;
ввести дополнительную переменную s1. В цикле делать:
s1:='insert into ... values ('+dl[1]+','+...;
memo1.lines.add(s1);
Кстати, а почему в запросе нет перечисления полей, которым присваиваются значения? Есть опасность нарваться на неприятность - если порядок полей в таблице не совпадет с порядком перечисления значений.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 5 сентября 2008, 20:00 [#5]:

to Вадим К : переменая s уже используется (а то "вопрошающий сделает так как написано" :-) и получит геморой)
Вадим К

Вадим К (статус: Академик), 5 сентября 2008, 20:04 [#6]:

и что, будет работать. посмотрите внимательней:) После присваивания она уже не нужна и можно использовать снова
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 5 сентября 2008, 20:05 [#7]:

to Вадим К:ЧП мирового масштаба не получиться - там стоит try finally end
просто строка не добавиться в memo.
Да и еще to Felixx: вынесите строки dl:=TStringList.create и dl.free и конструкцию try finally end из цикла и используйте проверку, предложенную Вадим К .
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 5 сентября 2008, 20:07 [#8]:

to Вадим К:Переменная то уже не нужна, но у Вас написано s:=s+..., то есть все что было в строке s, добавиться в memo
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 5 сентября 2008, 20:07 [#9]:

Было написано :-) Вы поправились
Вадим К

Вадим К (статус: Академик), 5 сентября 2008, 20:09 [#10]:

to Мережников Андрей
Ну раз уж так:)
Лучше получить ShowMessage с ругательством, чем просто будет проглочено неверную строку без каких то замечаний.
Конечно, для релиза эту строку лучше заменить на что то более внятное с выводом номера строки в файле, например.
А вообще для отладки удобно использовать так называемые "утверждения" - assert
----
Поправился, ибо умею:)
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 5 сентября 2008, 20:15 [#11]:

to Вадим К: Про проверку, которую Вы предложили, я уже написал (там где советую вынести создание dl за пределы цикла - зачем переменную много раз создавать, а потом уничтожать? вдруг проц перегреется? :-)). На самом деле - зачем лишние тормоза?
Felixx

Felixx (статус: Посетитель), 5 сентября 2008, 20:36 [#12]:

Большое спасибо вам за ответы, первую часть того чего хотел реализовал)
В конечном результате вышел такой Код:

[code]

procedure TForm1.Button4Click(Sender: TObject);
var
s:string;
dl:TStringList;
i:integer;
begin

for i:=0 to Memo2.Lines.Count-1 do
begin
s:= Memo2.Lines[0+i];
dl:=TStringList.create;
try
dl.Delimiter:=#9;
dl.DelimitedText:=s;
if dl.count < 9 then ShowMessage('Битый файл')
else
begin
s:='INSERT INTO `recitems` VALUES' + '('+dl[1]+','+dl[8]+','+'0'+');';
Memo1.lines.add(s);
end;
finally
dl.free;
end;
end;
end;

[/code]

Теперь осталось самое сложное думаю..
например строка:
INSERT INTO `recitems` VALUES(1,[0(1864)],[4(1869)],0);
в предпоследнем значении у нас выходит строка [0(1864)],[4(1869)]
так вот мне нужно что бы то что в скобках [..] писалочь отдеотно в новую строку... например вот так должен был получиться запрос:
INSERT INTO `recitems` VALUES(1,1666,1864,0,0);
INSERT INTO `recitems` VALUES(1,1666,1869,4,0);

Это думаю тоже нужно как то в массив впихать ...
Felixx

Felixx (статус: Посетитель), 5 сентября 2008, 20:44 [#13]:

Поясню, в SQL
1е значение - ID рецепта.
2е значение - ID Первой вещи для изготовления рецепта.
3е значение - Количество первой вещи.
4е значение - если вещ для изготовления рецепта имеет свой рецепт записать его ID , эти ID находятся в dl [2]

Поправочка из вышесказанного... вот правельный запрос:
INSERT INTO `recitems` VALUES(1,1864,0,0);
INSERT INTO `recitems` VALUES(1,1869,4,0);

А если например у нас в [..] 5 или 6 вещей требуется то нужно сделать 5-6 запросов для этого ID рецепта..
Как такое можно реализовать?
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 5 сентября 2008, 21:57 [#14]:

например так:
s:='insert into... values('+dl[1]+',[],0)';
s1:=trim(dl[8]);
repeat
x:=pos(']',s1);
if x=0
then begin
s2:=ansireplacestr(s,'[]',s1);
s1:='';
end
else begin
s3:=copy(s1,2,x-2);
s1:=copy(s1,x+2,length(s1);//тут надо предусмотреть проверку, чтобы между ] и [ был только один символ
//разбираем строку s3
x:=pos('(',s3);
s4:=leftstr(s3,x-1);
s3:=rightstr(s3,length(s3)-x);
x:=pos(')',s3);
s4:=leftstr(s,x-1)+','+s4;
s2:=ansireplacestr(s,'[]',s4);
end;
memo1.lines.add(s2);
until s1='';

И все таки - укажите список полей перед values : insert into таблица (список полей) values(список значений); А то переделает кто-нибудь структуру таблицы и всю прогу переписывать
Felixx

Felixx (статус: Посетитель), 5 сентября 2008, 22:10 [#15]:

Структуру таблицы не переделают, исходный файл тоже)))
Программка нужна всего на 1 раз :(

По сути это из файла клиента игры, мы берем и заполняем таблицу SQL..
на данный момент реализовал в программе такой вывод SQL:

INSERT INTO `recitems` VALUES(1,1864)],2,0);
INSERT INTO `recitems` VALUES(1,1869)],2,0);
INSERT INTO `recitems` VALUES(2,2005)],18,0);
INSERT INTO `recitems` VALUES(2,1869)],18,0);
INSERT INTO `recitems` VALUES(2,1870)],18,0);
INSERT INTO `recitems` VALUES(3,2006)],12,0);
INSERT INTO `recitems` VALUES(3,1869)],12,0);
INSERT INTO `recitems` VALUES(3,1872)],12,0);
INSERT INTO `recitems` VALUES(3,1864)],12,0);

Осталось
1) Заменить ")]", на" ,"
2) Огранизовать поиск последнего значения...

Если нужно могу выложить исходники, посмотрите что я там натворил, мож какие получше идеи будут)
если нужно то выложу...
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 5 сентября 2008, 22:18 [#16]:

заменить )] на запятую можно одной строкой кода:
AnsiReplaceStr(memo.text,')]',','); только не забудьте подключить модуль StrUtils;
"Программка нужна всего на 1 раз" - как знать, а вдруг еще пригодится?
На будущее советую все таки указывать список полей. Удачи в дальнейшем решении.
Felixx

Felixx (статус: Посетитель), 6 сентября 2008, 05:12 [#17]:

Всем большое спасибо :) вот что у меня получилось...
http://plusfile.ru/8003435
кое что конесчно не реализовал, в том числе проверку на то что с исходного файла нельзя удалять 1ю строку... но принципе работает)
Может кто - нить что предложит свое?)
Вадим К

Вадим К (статус: Академик), 6 сентября 2008, 12:23 [#18]:

А смысл, если это "одноразовая задача". В таких задачах оправданны любые "грязные трюки", главное, что бы выполнило свою работу.
Галочка "подтверждения прочтения" - вселенское зло.
Felixx

Felixx (статус: Посетитель), 6 сентября 2008, 16:29 [#19]:

Ну как бы хочется научиться делать программы правильно :)
Не люблю "Грязные штучки" :)

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:38
Выполнено за 0.03 сек.