Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.07.2011, 18:25   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию цикл for i:=0 to count -1 do. Уменьшать счётчик i внутри цикла...

Доброго времени суток! Пишу приложение нужно сортировать список файлов.. вот функция:

Код:
function CheckForNewFiles(aNewFilesList, AoldFilesList: TStrings): boolean;
var
  i, i2: integer;
  s, s1, s3: string;
  m1, m2: string;
//  FilesNum:integer;
begin
  If AoldFilesList.Count = 0 then
  begin
    Result := True;
    Exit;
  end;
  for i2 := 0 to aNewFilesList.Count - 1 do
  begin
    s := GetFileNameFromData(aNewFilesList.Strings[i2]);
    s3 := AoldFilesList.Text;
    if Pos(s, s3) = 0 then
    begin
      Continue; // переход к сл. интерации
    end
    else
    begin
    //имя одинаковое но есть в разных списках
      m1 := GetFileHashFromDataByName(s, aNewFilesList);
      m2 := GetFileHashFromDataByName(s, AoldFilesList);
      if CompareFilesByMd5(m2, m1) then
      begin
        {
          Файл старый и хеши совпали, значит этот файл ужебыл в закачках и он закачан
          На сервере нового нет...
        }
        // если хеши совпадают
        aNewFilesList.Delete(i2);
        {
        Покажем что нужно откатиться на 1 назад т.е. из файла удалена 1 строка.
        }
        i2:=i2-1; //потому что число файлов уменьшилось на 1 и отсчёт нужно начинать с 0.
        // Переход к след. интерациии..
        Continue;
      end
      else
      begin
        // Хеши не совпадают
        Continue; //пропускаем файл...
      end;
    end;
  end;
  if (aNewFilesList.Count = 0) then
    Result := False
  else
    Result := True;
end;
проблема:
Код:
      begin
        {
          Файл старый и хеши совпали, значит этот файл ужебыл в закачках и он закачан
          На сервере нового нет...
        }
        // если хеши совпадают
        aNewFilesList.Delete(i2);
        {
        Покажем что нужно откатиться на 1 назад т.е. из файла удалена 1 строка.
        }
        i2:=i2-1; //потому что число файлов уменьшилось на 1 и отсчёт нужно начинать с 0.
        // Переход к след. интерациии..
        Continue;
      end
      else
      begin
        // Хеши не совпадают
        Continue;
      end;
Удаляя строку уменьшаем счётчик строк на 9.
Но при этом, номер текущей(i2) строки не изменяется..

До выполнения delete, ANewFilesList.Count = 10
После выполнения delete, ANewFilesList.Count = 9

До выполнения delete, i2 = 0
После выполнения delete, i2 = 1 (Должен стать 0)

Так вот после выполнения delete, i2 нужно уменьшить на один чтобы отсчёт снова вести с 0...

В коде я это показал:
i2:=i2-1;

Но компилятор не даёт этого сделать. Почему?
Ошибка:
[DCC Error] MiscUnit.pas(176): E2081 Assignment to FOR-Loop variable 'i2'

Подсабите решением.

----------------------------

Есть вариант просто создать TSTemp:Tstrings;
и в него записывать новые файлы. Затем старый список чистить, а на его место ставить данные из TSTemp:Tstring;
Но думаю есть решение и моей проблеме...

Последний раз редактировалось Человек_Борща; 01.07.2011 в 18:30.
Человек_Борща вне форума Ответить с цитированием
Старый 01.07.2011, 18:31   #2
execom
Редкий тунеядец
Форумчанин
 
Аватар для execom
 
Регистрация: 29.10.2006
Сообщений: 595
По умолчанию

переменную итерации нельзя менять в рамках цикла.. например такой код тоже не за работает
Цитата:
for i:=1 to 10 do i:=i-1;
кстати это сдаланно для того что бы конструкции подобные приведенной выше не приводили к вечным циклам)

Советую сокращать количество циклов банальным выходом по break)

Последний раз редактировалось execom; 01.07.2011 в 18:34.
execom вне форума Ответить с цитированием
Старый 01.07.2011, 18:34   #3
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Ну, вместо цикла for попробуйте пользовать while.
_-Re@l-_ вне форума Ответить с цитированием
Старый 01.07.2011, 18:40   #4
ReportCube
Форумчанин
 
Аватар для ReportCube
 
Регистрация: 11.03.2011
Сообщений: 426
По умолчанию

for i2 := aNewFilesList.Count - 1 downto 0 do
ReportCube вне форума Ответить с цитированием
Старый 01.07.2011, 18:56   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Если вместо TStrings использовать TStringList, то там есть возможности автосортировки - свойства Sorted и CaseSensitive
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 01.07.2011, 19:52   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Если вместо TStrings использовать TStringList, то там есть возможности автосортировки - свойства Sorted и CaseSensitive
Как это помогло бы мне, если мне нужно изменить счётчик цикла?

Пака увидел для себя вариант:
Цитата:
Есть вариант просто создать TSTemp:Tstrings;
и в него записывать новые файлы. Затем старый список чистить, а на его место ставить данные из TSTemp:Tstring;
Но думаю есть решение и моей проблеме...
вполне работает.
Человек_Борща вне форума Ответить с цитированием
Старый 01.07.2011, 20:11   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

вам нужен просто цикл while aNewFileList.Count>0 do
внутри использовать нулевой индекс.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.07.2011, 20:40   #8
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

вероятность того что aNewFileList.Count = 0 очень мала.
Человек_Борща вне форума Ответить с цитированием
Старый 01.07.2011, 20:58   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

значит идите через while с ручным индексом цикла.
(если надо увеличивайте иначе нет)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 01.07.2011, 21:06   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

либо, как уже ранее предлагалось, использовать условный цикл (while или repeat)
но много лучше использовать технику, которую уже предложил ReportCube в пост #4

Код:
for i2 := aNewFilesList.Count - 1 to 0 do
  begin
    s := GetFileNameFromData(aNewFilesList.Strings[i2]);
    if НУЖНОЕ_УСЛОВИЕ_ДЛЯ_УДАЛЕНИЯ then
        // если хеши совпадают
        aNewFilesList.Delete(i2);
  end;

p.s.
про этот УЖАС
Цитата:
Код:
    s3 := AoldFilesList.Text;
    if Pos(s, s3) = 0 then
я уже молчу... мало того, что строка s3 присваивается в цикле,
так ещё про методы IndexOf и Find забыли? Или они чем-то не подходят, нужно именно в цикле брать .Text и искать вхождение строки?!

Последний раз редактировалось Serge_Bliznykov; 01.07.2011 в 21:10.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
счётчик (цикл в цикле) PARTOS Microsoft Office Excel 3 26.10.2010 21:13
Оператор цикла с постусловием (цикл REPEAT) 0001 Помощь студентам 3 18.01.2010 00:02
счётчик цикла Kivin13 Общие вопросы Delphi 3 11.09.2007 12:57