Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #16  
Старый 19.06.2011, 22:22
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Классы TList и TStringList используют метод QuickSort. Основная разница между классами в том, что в TList грузим объекты (ссылки на них), а в TStringList строку и при необходимости объект с ним связанный. Выбирай какой класс больше подходит под задачу.
Ответить с цитированием
  #17  
Старый 21.06.2011, 21:43
us8ihj us8ihj вне форума
Прохожий
 
Регистрация: 18.06.2011
Сообщения: 19
Репутация: 10
По умолчанию

Итак я со стринглистом разобрался. Раньше было через невидимое Memo, строки в которые добавлялись из потока. Со StringList'ом всё тоже самое, только это абстрактный компонент. А вот с метотдами сортировки я не смог подружится. Читал информацию на одном форуме, там сранительно доступно было изложено, но я не понял как эти методы применить к моему случаю. Пришлось оставить свой алгоритм)
Ответить с цитированием
  #18  
Старый 21.06.2011, 22:00
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Используй AddObject, при этом в качестве строки может служить "Имя", а в качестве объекта - запись "Имя" + "Очки". Если Sorted = True сортировка происходит автоматически, иначе вызываем метод Sort.
Ответить с цитированием
  #19  
Старый 29.06.2011, 06:42
us8ihj us8ihj вне форума
Прохожий
 
Регистрация: 18.06.2011
Сообщения: 19
Репутация: 10
По умолчанию

Продолжая добивать програму по подсчету голосов, выводу рейтинга уперся в неочень заметную, но весьма неприятную вещь.
Фрагмент кода:
Код:
procedure TForm1.Button5Click(Sender: TObject);
var i,k,j:integer; f:textfile; s:string;
begin
ClearGrid(StringGrid1);
ClearGrid(StringGrid2);
if OpenDialog1.Execute then begin
assignfile(f,OpenDialog1.FileName);
reset(f);
 with StringGrid1 do
 begin
 i:=1;
  while not SeekEof(f) do
  begin
   while not SeekEoln(f) do
   begin
   read(f,s);
   Rows[i].Text:=StringReplace(s, #9, #13#10, [rfReplaceAll]);
   end;
   i:=i+1;
   readln(f);
   end;
     RowCount:=i;
 end;
end;
closefile(f);
...
...

1) Так вот, суть вопроса в том, что если нажать кнопку "открыть сохраненный результат" выскакивает проводник, предлагая выбрать путь к файлу. Если я выберу сохраненный файл, то всё нормально откроется. Если это окно OpenDialog закрыть, не выбрав файла - будет ошибка I\O Error 103. Можно ли это исправить?

2) И по ходу написания этого поста возник еще один вопрос. Дело в том что файл, в который сохраняется результат - текстового формата, и вида табулированной таблицы. Можно ли сделать так, что если файл не удовлетворяет виду
a1 b1 c1 d1 e1
a2 b2 c2 d2 e2
... ... ... ... ...

то ничего не будет открываться, либо же будет писаться сообщение.

3) Или второй вариант вопроса: Если имя файла имеет вид saved 29-06-2011 (то есть вида "saved dd-mm-yyyy"), а не какого-то там другого (вроде "Отчет по практике" или "1111")- он открывается, если иначе - ничего не происходит, или опять таки вывод сообщения ... ?

Буду благодарен за помощь!

Последний раз редактировалось us8ihj, 29.06.2011 в 08:43.
Ответить с цитированием
  #20  
Старый 29.06.2011, 08:42
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

closefile(f); из блока begin-end "if OpenDialog1.Execute then begin" вылетел. по остальному - можно.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #21  
Старый 29.06.2011, 08:43
us8ihj us8ihj вне форума
Прохожий
 
Регистрация: 18.06.2011
Сообщения: 19
Репутация: 10
По умолчанию

С OpenDialog разобрался. Всё работает как надо (причина была в том, что часть кода по обработке файла была после end'а OpenDialog.Execute.

Вопросы 2 и 3 остаются актуальными.
Ответить с цитированием
  #22  
Старый 29.06.2011, 08:57
us8ihj us8ihj вне форума
Прохожий
 
Регистрация: 18.06.2011
Сообщения: 19
Репутация: 10
По умолчанию

Цитата:
Сообщение от NumLock
closefile(f); из блока begin-end "if OpenDialog1.Execute then begin" вылетел. по остальному - можно.

Можно то можно, только как?.. Хотя бы на мысль наведи, а я попробую разобраться сам.

А вообще у меня есть идеи. Допустим сделать так: файл открыть, содержимое отправить в стринглист, и в ввиде массива обработать (а именно подсчитать количество стоблцов, опираясь на табуляторы). Второй вариант - отправить в невидимый стринггрид, подсчитать кол-во столбцов. Но это увеличит размер приложения, я думаю, да и кода будет больше. Если через стринггрид делать - то тут все понятно. А вот через стринглист - могут быть сложности. Это пока два варианта которые пришли мне в голову после бессонной ночи. Может есть что попроще, подскажите.

А по поводу имени файла - как можно реализовать такую процедуру "Если имя файла содержит слово "saved", пробел, слово ??-??-???? (где ? - цифра), то программа выполняется дальше"? Ну или что-то в этом роде.

Последний раз редактировалось us8ihj, 29.06.2011 в 09:02.
Ответить с цитированием
  #23  
Старый 29.06.2011, 10:47
Janom Janom вне форума
Начинающий
 
Регистрация: 04.02.2011
Адрес: Москва
Сообщения: 148
Версия Delphi: 7
Репутация: 133
По умолчанию

Функция проверки на имя:
Код:
function NameRevision(S:String):boolean;
const A: array [0..7] of byte = (7,8,10,11,13,14,15,16);
var i,x:Cardinal;
begin
Result:=True;
For i:=1 to Length(S) do
  if S[i]='\' then x:=i;
Delete(S,1,x);
Form1.Caption:=S;
if (Length(S)<>20) or (Pos('saved',S)<>1) or (S[6]<>' ') or (S[9]<>'-')
    or (S[12]<>'-') or (S[17]<>'.') or (S[18]<>'t')
    or (S[19]<>'x') or (S[20]<>'t') then
  begin
    Result:=False;
    exit;
  end;
for i:=0 to Length(A)-1 do
  if not (S[A[i]] in ['0'..'9'])then Result:=False;
end;
Вот как использовать:
Код:
if OpenDialog1.Execute then
  begin
    if NameRevision(OpenDialog1.FileName) then
      begin
        ShowMessage('Все КРУТО!!!');
        //Действия если все ништя и имя нам подходит...
      end else begin
        ShowMessage('Имя файла не соответствует необходимому!!!');
      end;
  end;
Ответить с цитированием
  #24  
Старый 29.06.2011, 11:19
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Ну реализовать проверку файла на верный набор данных можно несколькими способами.
1. Просто придумать свое уникальное расширение к имени файла. Метод простой и позволяет делать проверку на этапе выбора файла, но если данные все-же не совпадают по структуре, то получите ошибку.
2. В начале данных файла ставить уникальный маркер, который будет говорить вам о типе и версии файла.
3. И наконец полный предварительный анализ структуры данных.
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.

Последний раз редактировалось Страдалецъ, 29.06.2011 в 12:02.
Ответить с цитированием
  #25  
Старый 29.06.2011, 11:57
Janom Janom вне форума
Начинающий
 
Регистрация: 04.02.2011
Адрес: Москва
Сообщения: 148
Версия Delphi: 7
Репутация: 133
По умолчанию

Цитата:
Сообщение от Страдалецъ
Ну реализовать проверку файла на верный набор данных дынных можно несколькими способами.
1. Просто придумать свое уникальное расширение к имени файла. Метод простой и позволяет делать проверку на этапе выбора файла, но если данные все-же не совпадают по структуре, то получите ошибку.
2. В начале данных файла ставить уникальный маркер, который будет говорить вам о типе и версии файла.
3. И наконец полный предварительный анализ структуры данных.
Добавлю от себя что последний предпочтительнее.
А еще лучше комбинировать...
Ответить с цитированием
  #26  
Старый 29.06.2011, 17:34
us8ihj us8ihj вне форума
Прохожий
 
Регистрация: 18.06.2011
Сообщения: 19
Репутация: 10
По умолчанию

Понятно, но не всё. Ниже, в комментариях к строкам я написал что до меня дошло, а что неочень. Или же где-то сомневаюсь.
Код:
function NameRevision(S:String):boolean; //посылаем в функцию строку с именем файла 
const A: array [0..7] of byte = (7,8,10,11,13,14,15,16); //что это значит??
var i,x:Cardinal; //я так понимаю, можно было использовать integer
begin
Result:=True; //изначально предпологаем, что имя удовлетворяет виду.
For i:=1 to Length(S) do 
  if S[i]='\' then x:=i; // Тут ничего не понял. Особенно с косой чертой.
Delete(S,1,x);  //удаляем в строке с именем файла первый и иксовый элемент (со смещением влево).
Form1.Caption:=S;
if (Length(S)<>20) {тут понятно} or (Pos('saved',S)<>1) {если в строке S ниразу не встречается слово "saved"} or (S[6]<>' ') or (S[9]<>'-')
    or (S[12]<>'-') or (S[17]<>'.') or (S[18]<>'t')
    or (S[19]<>'x') or (S[20]<>'t') then // с остальными условиями ясно
  begin
    Result:=False; //возвращаем значение в ложь, если мы неубедили программу в том, что форма имени файла нам удовлетворяет
    exit; //а вот этот эксит для чего (или с чем) используется?
  end;
for i:=0 to Length(A)-1 do
  if not (S[A[i]] in ['0'..'9'])then Result:=False; //Тут что-то с байтами, я не понял.
end;


Извиняюсь, если много вопросов, но я хочу понять и полностью осознавать что делаю на 100%. Так в будущем будет меньше непоняток..)

Последний раз редактировалось us8ihj, 29.06.2011 в 17:36.
Ответить с цитированием
  #27  
Старый 29.06.2011, 18:14
Janom Janom вне форума
Начинающий
 
Регистрация: 04.02.2011
Адрес: Москва
Сообщения: 148
Версия Delphi: 7
Репутация: 133
По умолчанию

Код:
function NameRevision(S:String):boolean; //посылаем в функцию строку с именем файла 
const A: array [0..7] of byte = (7,8,10,11,13,14,15,16); //Номера символов которые должны быть буквами
var i,x:Cardinal; //Да, просто отрицательных порядковых номеров быть не может
begin
Result:=False;
if Length(S)=0 then exit; //Если строка пуста выходим из процедуры
Result:=True; //изначально предпологаем, что имя удовлетворяет виду.
For i:=1 to Length(S) do 
  if S[i]='\' then x:=i; // в пути к файлу ищем разделители последний остается в памяти
Delete(S,1,x);  //удаляем в строке с путем кфайлу все кроме имени файла
Form1.Caption:=S;//Это не надо тестил забул удалить))) 
if (Length(S)<>20) {тут понятно} or (Pos('saved',S)<>1) {если в строке S слово "saved" не первое или отсутствует} or (S[6]<>' ') or (S[9]<>'-')
    or (S[12]<>'-') or (S[17]<>'.') or (S[18]<>'t')
    or (S[19]<>'x') or (S[20]<>'t') then // с остальными условиями ясно
  begin
    Result:=False; //возвращаем значение в ложь, если мы неубедили программу в том, что форма имени файла нам удовлетворяет
    exit; //Выйти из функции т.к. имя нам уже не подходит
  end;
for i:=0 to Length(A)-1 do
  if not (S[A[i]] in ['0'..'9'])then Result:=False; //Проверка что стоит там где должны стоять цифры
end;
Ответить с цитированием
  #28  
Старый 29.06.2011, 22:16
us8ihj us8ihj вне форума
Прохожий
 
Регистрация: 18.06.2011
Сообщения: 19
Репутация: 10
По умолчанию

Теперь всё понятно, только поправочка:
Код:
const A: array [0..7] of byte = (7,8,10,11,13,14,15,16); //Номера символов которые должны быть цифрами
Я, кстати, минут 10 сидел и думал что это значит. А это оказалось, что это всего лишь массив, (0..7) который содержит в себе номера позиций чисел даты))
Спасибо за помощь!

Дальше буду пытаться реализовать проверку файла на его сожержимое. Впринципе на счет маркера было хорошо сказано, но если же в сохраненных файлах дописывать в первой строке шифр, то либо же он будет для всех один, либо если уникальный для каждого сохр. результата - то надо же иметь второй файл, в котором будут хранится список с этими шифрами. Кто-то что-то говорил о "третьем", способе проерки содержимого ("полный анализ структуры данных"). Можно чуть-чуть подробнее?

P.S. Функция запустилась с первого раза, работает так, как надо. Открывает только файлы, имя которых имеет вид "saved 29-06-2011"

Последний раз редактировалось us8ihj, 29.06.2011 в 22:25.
Ответить с цитированием
  #29  
Старый 29.06.2011, 22:26
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Куда уж подробнее, к примеру:
Код:
type
  TMyStruct = record
    id : string[8]; // 'My_table'
    ...
    bla-bla-bla
    ...
  end;

var
  MyStruct : TMyStruct
загружаем из файла кусок в структуру MyStruct и проверяем на соответствие с ранее записанными данными.
Ответить с цитированием
  #30  
Старый 29.06.2011, 22:32
us8ihj us8ihj вне форума
Прохожий
 
Регистрация: 18.06.2011
Сообщения: 19
Репутация: 10
По умолчанию

Цитата:
Сообщение от angvelem
загружаем из файла кусок в структуру MyStruct и проверяем на соответствие с ранее записанными данными.
Ну с куском из файла это понятно. А ранее записанные данные, как понять?
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 08:32.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter