Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [BCB6] TListBox - Обращение к определённой строчке, Как обратиться к определённой строчке. 
V
    Опции темы
MuForum
  Дата 3.8.2007, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: 1
Всего: 4



Доброе время суток!

Вчера столкнулся с такой проблемой, что мне при создание главной формы нужно было считать с файла данные, и затем проверить его на наличие запрещенных символов и если в какой-то строчке находиться запрещённый символ, то удалить эту строчку.

На первый взгляд всё просто и легко, но не тут то было, так как я провозился больше часа читая статьи из Google, так и не нашел то, что мне надо, затем психанул и уже сам методом логики и тыка решил свою проблему, поэтому решил и сдесь опубликовать решение, так как кто-то ещё может столкнуться с такой проблемой, и чтобы ему не приходилось ломать голову...

Задача: Проверить все строчки компонента TListBox на наличие запрещенных символов.
Цитата

Осуществлена проверка вводимого IP адреса:

    Если IP не формата Id1.Id2.Id3.Id4, то вы не запишете IP в файл/Строчка удалиться из файла.
    Если поле ввода IP пустое, то вы не запишете IP в файл/Строчка удалиться из файла.
    Если в поле ввода IP есть пробел, то вы не запишете IP в файл/Строчка удалиться из файла.





Вот и сам код:
Код

void __fastcall TForm1Main::CheckFilterFiles()
{
  for(int i=0; i<ListBox1->Items->Count; i++) // ListBox1->Items->Count - Количество строк в компоненте.
  {
    char T[255];
    sprintf(T, ListBox1->Items->operator[](i).c_str()); // Записываем в переменную char содержимое строчки. (ListBox1->Items->operator[](i) - Это указывание номера строки)
    int count1=0;
    int count2=0;
    int count3=strlen(T);
    for(int i2=0; i2<count3; i2++)
    {
    if(T[i2]==' ') count1++; // Если в строке есть пробел, то мы переменной count1 добавляем "+1".
    if(T[i2]=='.') count2++; // Если в строке есть точка, то мы переменной count2 добавляем "+1".
    }
    if(count1>0 || count2!=3 || count3==0) // Знак "||" означает или.
    {
    ListBox1->ItemIndex=i; // Пресваиваем номеру строки число переменной "i".
    ListBox1->Items->Delete(ListBox1->ItemIndex); // Удаляем из Items определённую строчку.
    ListBox1->Items->SaveToFile("Data\\"+FilterFileName); // Перезаписываем файл.
    i--; // Отнимаем от переменной "i" один пункт, так как мы удаляем строчку, и на место этой строчки приходит новая строчка, а её тоже надо проверить!
    }
  }
}



Теперь вопрос к опытным кодерам: Ребята, со стороны косметики функция правильно оформлена?

Это сообщение отредактировал(а) MuForum - 3.8.2007, 12:53


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
SenkraD
Дата 3.8.2007, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 9
Всего: 23



MuForum,  так пара замечаний
1. если что-то удаляеш иди с конца
2. ItemIndex можно не менять
3. Сохраняй уже в конце - время секономиш

Это сообщение отредактировал(а) SenkraD - 3.8.2007, 12:59


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
MuForum
Дата 3.8.2007, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: 1
Всего: 4



#2, SenkraD - Спасибо за советы, я учёл первые два и вот что получилось:

Код

  for(int i=ListBox1->Items->Count-1; i>-1; i--)
  {
    char T[255];
    sprintf(T, ListBox1->Items->operator[](i).c_str());
    int count1=0;
    int count2=0;
    int count3=strlen(T);
    for(int i2=0; i2<count3; i2++)
    {
    if(T[i2]==' ') count1++;
    if(T[i2]=='.') count2++;
    }
    if(count1>0 || count2!=3 || count3==0)
    {
    ListBox1->ItemIndex=i;
    ListBox1->Items->Delete(ListBox1->ItemIndex);
    ListBox1->Items->SaveToFile("Data\\"+FilterFileName);
    }
  }



P.S. -> Третий сейчас думую как реализовать(Если можешь подскажи через что правильнее будет это реализовать)

- Идея примерно вот такая:

Код

  for(int i=ListBox1->Items->Count-1; i>-1; i--)
  {
    char T[255];
    sprintf(T, ListBox1->Items->operator[](i).c_str());
    int count1=0;
    int count2=0;
    int count3=strlen(T);
    for(int i2=0; i2<count3; i2++)
    {
    if(T[i2]==' ') count1++;
    if(T[i2]=='.') count2++;
    }
    if(count1>0 || count2!=3 || count3==0)
    {
    Тут записываем номер строчки в какуе-то переменную.
    {
  }
  for(int i=0; i< длины переменной; i++)
    {
    ListBox1->ItemIndex=i;
    ListBox1->Items->Delete(ListBox1->ItemIndex);
    ListBox1->Items->SaveToFile("Data\\"+FilterFileName);
    }



--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
zkv
Дата 3.8.2007, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 1
Всего: 92



по поводу:
Цитата(MuForum @  3.8.2007,  12:49 Найти цитируемый пост)
Ребята, со стороны косметики функция правильно оформлена?

вот мое мнение, в комментариях ;)
Код

//функция делает что то этакое, через такую то фигню. те описание тут дб (или в хедере)
void __fastcall TForm1Main::CheckFilterFiles()
{
    //цикл делания чего-то там
    //ListBox1 - мягко говоря, неудачное названия
    for(int i=0; i<ListBox1->Items->Count; i++)// ListBox1->Items->Count - Количество строк в компоненте.//лишний комментарий (лучше уж без него)
    {
        char T[255];
        sprintf(T, ListBox1->(*Items)[i].c_str());// Записываем в переменную char содержимое строчки. (ListBox1->Items->operator[](i) - Это указывание номера строки)//лишний комментарий (лучше уж без него) 
        int count1=0;//за такие названия пальцы ломать надо :)
        int count2=0;//тоже самое 
        int count3=strlen(T);//тоже самое 
        //можно описать что делает цикл, если неочевидно
        for(int i2=0; i2<count3; i2++)
        {
            if( T[i2]==' ') count1++; // Если в строке есть пробел, то мы переменной count1 добавляем "+1".//лишнее
            if( T[i2]=='.') count2++; // Если в строке есть точка, то мы переменной count2 добавляем "+1".//лишнее
        }//можно добавить типа: i2<count3
        //можно тоже пояснить, я с первого взгляда не уловил что делается в след. блоке
        if(count1>0 || count2!=3 || count3==0)// Знак "||" означает или.//Это ты вообще кому сообщаешь?
        {
            ListBox1->ItemIndex=i;// Пресваиваем номеру строки число переменной "i".//лишний комментарий (лучше уж без него)
            ListBox1->Items->Delete(ListBox1->ItemIndex);//то что удаляем понятно по коду, лучше бы пояснил что за "определенная строчка":  // Удаляем из Items определённую строчку.
            ListBox1->Items->SaveToFile("Data\\"+FilterFileName);// Перезаписываем файл. //в таком виде комментарий неуместен
            i--; // Отнимаем от переменной "i" один пункт, так как мы удаляем строчку, и на место этой строчки приходит новая строчка, а её тоже надо проверить!
        }
    }//можно добавить типа: i<ListBox1->Items->Count
}//можно добавить типа: TForm1Main::CheckFilterFiles()

Резюме: если взялся комментировать, то комментарии должны помогать в разборе кода, а не отвлекать от него ;)
PM MAIL   Вверх
SenkraD
Дата 3.8.2007, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 9
Всего: 23



Ну zkv почти во всё прав.
А сохранку делай после того как цикл отработает!!!
И не меняю ItemIndex - тратиш время на отрисовку

Это сообщение отредактировал(а) SenkraD - 3.8.2007, 13:45


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
MuForum
  Дата 3.8.2007, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: 1
Всего: 4



#4, zkv - Склефосовский, перед тем, чтобы что-то написать надо подумать, и оскорблять человека из-за того, что ог начинающий программист не стоит, так как когда-то и ты начинал...

2) sprintf(T, ListBox1->(*Items)[i].c_str()); - [C++ Error] Main.cpp(566): E2280 Member identifier expected
- Сначала проверять свой код надо, а затем писать...

3) int count1=0;//за такие названия пальцы ломать надо smile - Какая разница как переменная называется...

P.S. -> От таких комментариев тошнит...


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
SenkraD
Дата 3.8.2007, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 9
Всего: 23



MuForum
Цитата(MuForum @  3.8.2007,  13:45 Найти цитируемый пост)
Какая разница как переменная называется...

 доростёш - поймёш

можно вообще не создавать эту чаровскую строку с завершающим нулём, а работать через методы ListBox1->Items->Strings[индекс]->нужный метод

Это сообщение отредактировал(а) SenkraD - 3.8.2007, 13:48


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
MuForum
  Дата 3.8.2007, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: 1
Всего: 4



#5, SenkraD - Спасибо за помощь!

На счёт не спал, ты прав, я пошел спать почти в 5 утра, в 7 был подъём, гулять с собакой и мамке помогать, а вчерашний жень весь за компьютером провёл, так что не суди строго из-за того, если туплю!


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
zkv
Дата 3.8.2007, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 1
Всего: 92



Цитата(MuForum @  3.8.2007,  13:45 Найти цитируемый пост)
Склефосовский, перед тем, чтобы что-то написать надо подумать, и оскорблять человека из-за того, что ог начинающий программист не стоит, так как когда-то и ты начинал...

в мыслях не было никого оскорблять, притом я не сам полез с критикой, сам попросил...
я бы спасибо сказал в свое время, если бы мне кто-нибудь так помогал. 
Удачи!  smile 

ps если будет время, загляни сюда

Это сообщение отредактировал(а) zkv - 3.8.2007, 13:57
PM MAIL   Вверх
MuForum
Дата 3.8.2007, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: 1
Всего: 4



#9, zkv - Да ты извини если что, просто мне было не приятно читать, что я чуть-ли не баламут от того, что ещё зелёный и неопытный...

P.S. -> Спасибо тебе за критику конечно, просто немного мягче это надо делать, так как многие только начинают заниматься программированием! (Я лично только как месяц начал). 


p.S. -> Ещё раз спасибо парни, что указали на ошибки и поправили меня!

Это сообщение отредактировал(а) MuForum - 3.8.2007, 13:57


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
MuForum
Дата 3.8.2007, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: 1
Всего: 4



# for all - Вот что в итоге получилось:

Код

 for(int i=ListBox1->Items->Count-1; i>-1; i--)
 {
  char T[255];
  sprintf(T, ListBox1->Items->Strings[i].c_str());
  int c1=0;
  int c2=0;
  for(int i2=0; i2<ListBox1->Items->Strings[i].Length(); i2++)
  {
  if(T[i2]==' ') c1++;
  if(T[i2]=='.') c2++;
  }
  if(c1>0 || c2!=3 || ListBox1->Items->Strings[i].Length()==0) ListBox1->Items->Delete(i);
 }
 ListBox1->Items->SaveToFile("Data\\"+FilterFileName);



Пробовал сделать по другому, но выдаёт еррор при запуске уже самой программы:
Код

 for(int i=ListBox1->Items->Count-1; i>-1; i--)
 {
  int c1=0;
  int c2=0;
  for(int i2=0; i2<ListBox1->Items->Strings[i].Length(); i2++)
  {
  if(ListBox1->Items->Strings[i][i2]==' ') c1++;
  if(ListBox1->Items->Strings[i][i2]=='.') c2++;
  }
  if(c1>0 || c2!=3 || ListBox1->Items->Strings[i].Length()==0) ListBox1->Items->Delete(i);
 }
 ListBox1->Items->SaveToFile("Data\\"+FilterFileName);


Вот содержимое ошибки: Project ConnectServer.exe raised exception class ERangeError with  message ". Process stoped. Use Step or Run to continue.


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
SenkraD
Дата 3.8.2007, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 9
Всего: 23



MuForum, у типа String индексания идёт с 1 до Length() включительно
Код

 for(int i=ListBox1->Items->Count-1; i>-1; i--)
 {
  int c1=0;
  int c2=0;
  for(int i2=1; i2<=ListBox1->Items->Strings[i].Length(); i2 ++)
  {
  if(ListBox1->Items->Strings[i][i2]==' ') c1++;
  if(ListBox1->Items->Strings[i][i2]=='.') c2++;
  }
  if(c1>0 || c2!=3 || ListBox1->Items->Strings[i].Length()==0) ListBox1->Items->Delete(i);
 }
 ListBox1->Items->SaveToFile("Data\\"+FilterFileName);


Это сообщение отредактировал(а) SenkraD - 3.8.2007, 15:09


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
xKOCMOCx
Дата 3.8.2007, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 3.8.2007

Репутация: нет
Всего: нет



А вот моё мнение.
Во-первых зачем вообще прорисовывать  листбокс, есть же класс:
Код

const short size = 255;
TList *list = new TList[size];

 for(int i = list -> Count - 1; i > -1; i --)
  {
    char T[size];
    sprintf(T, (char*)list -> operator [](i));
    int count1 = 0;
    int count2 = 0;
    int count3 = strlen(T);
    for(int i2 = 0; i2 < count3; i2 ++)
    {
    if(T[i2] == ' ') count1 ++;
    if(T[i2] == '.') count2 ++;
    }
    if(count1 > 0 || count2 != 3 || count3 == 0)
    {
     list -> Delete(i);
    }
  }


Во-вторых можно сделать проще:
Код

char *path = new char[512],*mas = new char[1024];
path = "c:\\1.txt";
FILE *f = fopen(path,"rt"), *ff;
path[3] = '2';
      ff = fopen(path,"wt");

while(fgets(mas, 1024, f))
{
if(!strrchr(mas, ' ') && !strrchr(mas, '.'))
fprintf(ff, "%s", mas);
}
fclose(f);
fclose(ff);

Так я думую будет быстрее  smile 
PM MAIL   Вверх
MuForum
Дата 6.8.2007, 02:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 427
Регистрация: 13.6.2007
Где: Молдова, Кишинев

Репутация: 1
Всего: 4



# for all - Ребята есть ещё одна проблема, пытался решить но что-то не выходит...

Задача: Проверить есть ли повторяющие IP адреса, если есть - то удалить.

Код

 for(int i3=ListBox1->Items->Count-1; i3>-1; i3--)
 {
  AnsiString T=ListBox1->Items->Strings[i3];
  for(int i4=ListBox1->Items->Count-2; i4>-1; i4--)
  {
   if(ListBox1->Items->Strings[i4]==T)
   {
    ListBox1->Items->Delete(i4);
    i3--;
   }
  }
 }
 ListBox1->Items->SaveToFile(FileDir+"Data\\"+FilterFileName);



P.S. -> Но почему-то функция работает ни так как надо, понять почему не многу...


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа!" (Р. Шекли)
PM MAIL WWW ICQ Skype MSN   Вверх
SenkraD
Дата 6.8.2007, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 9
Всего: 23



MuForum, у меня щас нету справки по Builder, но точно знаю, что есть свойство связаное с дублированием, по крайней мере у TList точно есть.
А так вообще:
Код

bool bIsRetry;

bIsRetry = true;
while(bIsRetry)
{
    bIsRetry = false;
    for(int i = ListBox1->Items->Count - 1; i >=0; i --)
    {
        if(ListBox1->Items->Strings[i] == ListBox1->Items->Strings[i - 1])
       {
            ListBox1->Items->Delete(i);
            bIsRetry = true;
       }
    }
}
ListBox1->Items->SaveToFile(FileDir+"Data\\"+FilterFileName);


P.S. Писал на скорую руку - особо не хаять


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0971 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.