Забор Что можно написать на заборе? Да все, что угодно!
Ответить
Перейти к новому Перейти к новому   Опции темы Опции просмотра
вопрос по с++ | by TEMA4
Непрочитано 02.07.2007, 18:37   # 1
 
Регистрация: 10.06.2006
Адрес: Питер, юго-запад
Возраст: 37
Сообщений: 694
Байк: старый, но крепкий питбуль :)
Отправить сообщение для TEMA4 с помощью ICQ
TEMA4 вне форума
По умолчанию вопрос по с++
мне нужно чтоб программа открывала текстовые файлы, например с расширением log, причём она должна начать с заданной пользователем папки и далее искать во всех вложенных. как это вообще можно сделать? а то я могу открыть тока заданный файл.. можно было сделать конечно на bash с регулярными выражениями но нужно именно под винду(((
ну или где про это почитать можно? я у страуструпа чего-то не нашёл....
заранее спасибо)
Цитата
Непрочитано 02.07.2007, 19:08   # 2
 
Аватар для t.w.o.
 
Регистрация: 22.07.2006
Адрес: Москва м.Бабушкинская
Возраст: 34
Сообщений: 6,663
Записей в дневнике: 1
Байк: Speed Race Solo 26
Отправить сообщение для t.w.o. с помощью ICQ
t.w.o. вне форума
может DC++, или нет, знач я такой не знаю
Цитата
Непрочитано 02.07.2007, 19:22   # 3
 
Регистрация: 08.11.2005
Сообщений: 1,123
Отправить сообщение для mil_alex с помощью ICQ
mil_alex вне форума
для си/си++ есть функция findfirst() которая получает шаблон, например строку "*.*" и проводит поиск первого совпадающего с шаблоном элемента каталога (файла или подкаталога). Затем вызывают findnext() и продолжают ее вызывать пока она возвращает положительный результат. При этом функции заполняют информацией структуру, в которой оказывается имя, длина, атрибуты, время создания файла и т.п.

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

если не пользоваться ф-циями стандартной библиотеки си/си++, тогда на WinAPI32 это выглядит как FindFirstFile() и FindNextFile + FindClose, которые работают точно так же как и рантайм библиотеки си/си++
Цитата
Непрочитано 02.07.2007, 19:30   # 4
 
Регистрация: 08.11.2005
Сообщений: 1,123
Отправить сообщение для mil_alex с помощью ICQ
mil_alex вне форума
во кусок оч старого кода)
Код:
static int ProcessFolder3(int level)
{
   HANDLE hFind;
   WIN32_FIND_DATA fnd;
   bool flag;

   int found=0; // have found something in this folder?

   hFind = FindFirstFile( "*.*", &fnd );
   flag=TRUE;

   if (hFind != INVALID_HANDLE_VALUE )
   while (flag)
   {
      if ( fnd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
      {
         if ( *((short *) &fnd.cFileName[0] ) == 0x002E ) goto b; // skip "."
         if ( (*((uint *) &fnd.cFileName[0] ) & 0x00FFFFFF) == 0x002E2E ) goto b; // skip ".."

         found++;

         if (SetCurrentDirectory(fnd.cFileName))
         {
            int old_path_len = strlen(my_path);
            strcat(my_path, fnd.cFileName); // append this folder name
            strcat(my_path, "\\");
            int f=ProcessFolder3(level+1);
            if (! SetCurrentDirectory(".."))
            {
               printf("error: can't cd ..\n");
               break;
            }
            my_path[old_path_len] = 0; // trim this folder name
            if (!f)
            {
               if (level) RemoveDirectory(fnd.cFileName);
            }
         }
         else
         {
            printf("error: can't cd '%s'\n", fnd.cFileName);
            break;
         }

         goto b;
      }

      strcpy(this_file, fnd.cFileName ); // local
      wsprintf( target_file, "%s%s%s", target_path, my_path, fnd.cFileName );
      found++;

      b:
      flag=FindNextFile( hFind, &fnd );
   }
   else
      found = 1; // for safety, do not assume failed directories empty
       
   FindClose(hFind);
   return found;
}
не надо его запускать) он если я верно помню стирает пустые вложенные каталоги. Просто как примерчеГ
Цитата
Непрочитано 02.07.2007, 19:38   # 5
 
Регистрация: 10.06.2006
Адрес: Питер, юго-запад
Возраст: 37
Сообщений: 694
Байк: старый, но крепкий питбуль :)
Отправить сообщение для TEMA4 с помощью ICQ
TEMA4 вне форума
круто) спасибо большое, ща буду разбираться!
Цитата
Непрочитано 02.07.2007, 19:48   # 6
 
Регистрация: 08.11.2005
Сообщений: 1,123
Отправить сообщение для mil_alex с помощью ICQ
mil_alex вне форума
вдогонку, открыть файл для чтения это
FILE *f = fopen(name, "r");

далее
while (fgets(буфер, его размер, f))
{
// тут делаем со строкой в буфере чо нада
}
и в конце fclose(f);

в хелпе эти слова должны быть)

а на винапи32
HANDLE h = CreateFile(непомню));
ReadFile(буфер, размер, скока было прочитано, h); // примерно так
CloseHandle(h); // в конце
Цитата
Непрочитано 03.07.2007, 14:48   # 7
 
Регистрация: 10.06.2006
Адрес: Питер, юго-запад
Возраст: 37
Сообщений: 694
Байк: старый, но крепкий питбуль :)
Отправить сообщение для TEMA4 с помощью ICQ
TEMA4 вне форума
такой ещё вопрос созрел:

мне нужно искать файлы *.log в каталоге который передан как параметр через командную строку.
передаю вот так int main(int argc, char* argv[]) - то есть имя каталога у меня будет в argv[1].
файлы ищу с помощью findfirst()
findfirst("*.log", &ffblk,0); так я найду все файлы в текущем каталоге.. а как туда приделать ещё каталог переданный через командную строку? а то тут у меня постоянно всякие несоответствия...
findfirst(argv[1] + "*.log", &ffblk,0); - так не работает
Цитата
Непрочитано 03.07.2007, 15:33   # 8
 
Регистрация: 08.11.2005
Сообщений: 1,123
Отправить сообщение для mil_alex с помощью ICQ
mil_alex вне форума
мелкое замечаньице: прежде чем в проге использовать argv[] с любым ненулевым индексом, надо проверить argc и убедиться, что оно больше единицы, т.е. када прога без параметров запускается, то argc=1 и argv[0] содержит путь к её файлу exe, а во всех остальных случаях надо проверить например что argc действительно ==2 и после этого пользоваться строкой из argv[1], иначе потенциальный баг будет.

соединить строки можно strcat(a, b) (вместо перегруженного оператора + ) и вроде в хелпе пишут что вот так
findfirst("c:\\dos\\test\\*.log", бла-бла
вроде можно и будет работать)

вообще я делал иначе, не уверен что так будет лучше - но оно работало))

берем каталог из командной строки и делаем туда cd то есть change dir. Он станет текущим, после чего там findfirst("*.log", бла-бла
Когда от findnext() выяснится что больше подходящих файлов нема, можно сделать cd обратно в каталог, откуда программа была запущена.

это см. про getcurdir() chdir() и их аналоги.


и еще, для пущей безопасности, лучше не использовать место в памяти, выделенное операционкой под массив параметров командной строки, в своих целях. То есть, не копировать "в" argv[] ничего и не присоединять к его имеющимся строкам другие строки.

т.е. вот как-то так:

char tmp[512];
strcpy(tmp, argv[1] ); // неплохо бы проверить длину строки и убедиться, что она влезет в 512 байт минус 1
strcat(tmp, "*.log"); // здесь то же самое, плюс надо проверить что последний символ в tmp это слэш (косая черта), и если юзер в командной строке указал путь без слэша в конце, добавить в tmp еще и слэш.
Цитата
Непрочитано 04.07.2007, 01:28   # 9
 
Регистрация: 03.07.2007
Адрес: Питер
Сообщений: 1
undirecthands вне форума
Код:
goto b;
Сорри за оффтоп, уписался когда увидел эту конструкцию
Цитата
Непрочитано 04.07.2007, 01:46   # 10
 
Регистрация: 08.11.2005
Сообщений: 1,123
Отправить сообщение для mil_alex с помощью ICQ
mil_alex вне форума
ааа я не религиозен. полстраны оттрахали моск Паскалем и люди со школьной скамьи конструируют невообразимой красоты лестницы (в смысле ступеньки) из вложенных if-ов, do...until-ов и прочих эндов с бегинами, вместо простых, читаемых и эффективных исходников))

тут кстати есть над чем в другом месте посмеяться - я вот думаю что будучи скомпилирован для моторола, код работать перестанет ввиду другого порядка байт в машинном слове. а у меня проверка является ли найденная строка (имя файла или каталога) "." или ".." выполнена одной командой сравнения двух целых чисел, вместо вызова ф-ции strcmp()
Цитата
Непрочитано 04.07.2007, 05:04   # 11
 
Регистрация: 10.06.2006
Адрес: Питер, юго-запад
Возраст: 37
Сообщений: 694
Байк: старый, но крепкий питбуль :)
Отправить сообщение для TEMA4 с помощью ICQ
TEMA4 вне форума
спасибо огромное) ты мозг!
параметры я проверял, но не подумал что в си можно использовать cd - хотя очень полезно) опять правда всякие проблемы начались(( завтра может разберусь..
Цитата
Непрочитано 04.07.2007, 09:53   # 12
 
Регистрация: 08.11.2005
Сообщений: 1,123
Отправить сообщение для mil_alex с помощью ICQ
mil_alex вне форума
незачто)
имелось в виду что можно и выполнить команду cd (посредством exec/system т.е. фактически вызвать command.com гыгы) и вызвать ф-цию смены каталога (не трогая командный процессор). Второе мне кажется надежнее)
Цитата
вопрос по с++ | by TEMA4
Ответить


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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 15:54.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot