Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Помогите с задачкой, правильно ли решил


Автор: eu8cc 31.5.2010, 18:47
Помогите с программкой, не могу понять как написать ее:

написать программу, находящую в заданном каталоге и всех его подкаталагах все файлы заданного размера. Имя каталога задается пользователем в качестве третьего аргумента командной строки. Диапазон (мин мах) размеров файлов задается пользователем в качестве первого и второго аргумента командной строки. Программа выводит результат поиска в файл(четвертый аргумент командной строки) в виде полный путь, имя файла, его размер. На консоль выводиться сообщения числа просмотренных файлов. 

На линуксе


Код

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <ftw.h>
#include <sys/stat.h>
#include <time.h>
#include <stdint.h>

size_t s1,s2; //размер файлов в диапазоне s1 <= x <= s2
FILE *f = NULL;

static int tree (const char *filename, const struct stat *status, int flag)
    if (flag == FTW_F && status->st_size >= s1 && status->st_size <= s2)
    {
        fprintf(f,"%-40s %-10jd %s\n",filename, (intmax_t) status->st_size);//пишем в файл
    }
    return 0; //возвращаем 0, чтобы продолжить обход дерева,иначе обход прерывается
}

int main (int argc,char* argv[])
{
    
    if (argc != 5)
    {    
        fprintf(stderr,"Не все параметры заданы\n");
        errno = EINVAL; //invalid arguments
        perror(argv[0]);
        printf("формат: нач_размер кон_размер папка имя_файла\n");
        return -1;    
    }    
    f = fopen (argv[4],"w+");    
    if ( f == NULL)
    {
        printf("NULL\n");
        fprintf(stderr,"Ошибка создания файла \"%s\"",argv[4]);
        perror(", ");
        return -1;
    }    */
    DIR *dr = opendir(argv[3]);    
    if (dr == NULL)    
    {
        fprintf(stderr,"Невозможно открыть директорию \"%s\"",argv[3]);
        fclose(f);
        errno = ENOENT;// no such file or directory
        perror(", ");
        return -1;
    }
    s1 = atol(argv[1]);
    s2 = atol(argv[2]);
    nftw(argv[3],tree,0, FTW_DEPTH || FTW_PHYS);    //обход дерева
    closedir(dr);
    fclose(f);
    return 0;
}


если есть возможность то проверьте работает ли код

Автор: Фантом 31.5.2010, 19:05
Ну, для начала, она просто не компилируется.  smile После 10-й строки забыта открывающая фигурная скобка, в 35-й зачем-то закрывается не открывавшийся до этого комментарий и т.д.

Ну и дурацкий вопрос - зачем стрелять из пушки по воробьям, если есть find? Или это такое учебное задание?

Автор: eu8cc 31.5.2010, 19:11
подправил
Код

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <ftw.h>
#include <sys/stat.h>
#include <time.h>
#include <stdint.h>

size_t s1,s2; //размер файлов в диапазоне s1 <= x <= s2
FILE *f = NULL;

static int tree (const char *filename, const struct stat *status, int flag)
    if (flag == FTW_F && status->st_size >= s1 && status->st_size <= s2)
    {
        fprintf(f,"%-40s %-10jd %s\n",filename, (intmax_t) status->st_size);//пишем в файл
    }
    return 0; //возвращаем 0, чтобы продолжить обход дерева,иначе обход прерывается

int main (int argc,char* argv[])
{
    
    if (argc != 5)
    {    
        fprintf(stderr,"Не все параметры заданы\n");
        errno = EINVAL; //invalid arguments
        perror(argv[0]);
        printf("формат: нач_размер кон_размер папка имя_файла\n");
        return -1;    
    }    
    f = fopen (argv[4],"w+");    
    if ( f == NULL)
    {
        printf("NULL\n");
        fprintf(stderr,"Ошибка создания файла \"%s\"",argv[4]);
        perror(", ");
        return -1;
    }    
    DIR *dr = opendir(argv[3]);    
    if (dr == NULL)    
    {
        fprintf(stderr,"Невозможно открыть директорию \"%s\"",argv[3]);
        fclose(f);
        errno = ENOENT;// no such file or directory
        perror(", ");
        return -1;
    }
    s1 = atol(argv[1]);
    s2 = atol(argv[2]);
    nftw(argv[3],tree,0, FTW_DEPTH || FTW_PHYS);    //обход дерева
    closedir(dr);
    fclose(f);
    return 0;
}


предложите еще как можно ее решить, вроде подправил, если есть возможность то проверте

Автор: Фантом 31.5.2010, 19:42
Цитата(eu8cc @  31.5.2010,  19:11 Найти цитируемый пост)
подправил

Незаметно. Первая из упомянутых ошибок никуда не делась
Цитата(eu8cc @  31.5.2010,  19:11 Найти цитируемый пост)

предложите еще как можно ее решить

Вот такой командой в консоли: find "стартовый каталог" -size +<минимальный размер> -size -<максимальный размер>.
Ну, например, что-то такое:
Код

find /home/user -size +800k -size -3M

Будет искать все файлы в /home/user и подкаталогах, с размером от 800 кб до 3 Мб.  Если требуется строго то поведение, которое описано выше, можно сляпать такой скрипт:
Код

#!/bin/sh
find $3 -size +$1 -size -$2 > $4
cat $4 | wc -l

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


Автор: eu8cc 31.5.2010, 19:53
а сейчас видно? )))
мне не нужен поиск с командной строки, а нужна программа которая ищет согласно заданным аргументам!!!
если можете то помогите пожалуйста

Код

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <ftw.h>
#include <sys/stat.h>
#include <time.h>
#include <stdint.h>

size_t s1,s2; //размер файлов в диапазоне s1 <= x <= s2
FILE *f = NULL;

static int tree (const char *filename, const struct stat *status, int flag)
{
    if (flag == FTW_F && status->st_size >= s1 && status->st_size <= s2)
    {
        fprintf(f,"%-40s %-10jd %s\n",filename, (intmax_t) status->st_size);//пишем в файл
    }
    return 0; //возвращаем 0, чтобы продолжить обход дерева,иначе обход прерывается
}
int main (int argc,char* argv[])
{
    
    if (argc != 5)
    {    
        fprintf(stderr,"Не все параметры заданы\n");
        errno = EINVAL; //invalid arguments
        perror(argv[0]);
        printf("формат: нач_размер кон_размер папка имя_файла\n");
        return -1;    
    }    
    f = fopen (argv[4],"w+");    
    if ( f == NULL)
    {
        printf("NULL\n");
        fprintf(stderr,"Ошибка создания файла \"%s\"",argv[4]);
        perror(", ");
        return -1;
    }    
    DIR *dr = opendir(argv[3]);    
    if (dr == NULL)    
    {
        fprintf(stderr,"Невозможно открыть директорию \"%s\"",argv[3]);
        fclose(f);
        errno = ENOENT;// no such file or directory
        perror(", ");
        return -1;
    }
    s1 = atol(argv[1]);
    s2 = atol(argv[2]);
    nftw(argv[3],tree,0, FTW_DEPTH || FTW_PHYS);    //обход дерева
    closedir(dr);
    fclose(f);
    return 0;
}



Автор: Фантом 31.5.2010, 20:10
Цитата(eu8cc @  31.5.2010,  19:53 Найти цитируемый пост)
мне не нужен поиск с командной строки, а нужна программа которая ищет согласно заданным аргументам!!!

Т.е. все-таки нужно одевать штаны через голову?

P.S. Ошибка сегментирования. 

Автор: eu8cc 31.5.2010, 20:24
Цитата(Фантом @  31.5.2010,  20:10 Найти цитируемый пост)
Т.е. все-таки нужно одевать штаны через голову?

 именно так, вот и приходится мучиться с этим кодом.

Автор: bilbobagginz 1.6.2010, 04:09
Цитата(eu8cc @  31.5.2010,  19:24 Найти цитируемый пост)
 именно так, вот и приходится мучиться с этим кодом.

судя по реакции на вопросы - явно не автору топика...

Автор: ller 1.6.2010, 10:58
если дали такое задание на учебе, то надо делать. И там кстати все задания, которые кто то уже решил, разбить на подстроки, заменить в массиве ну итд итп

Автор: eu8cc 1.6.2010, 18:22
У меня такое впечатление что никто здесь не разбирается в линуксе, я на большую половину решил задание, а никто не может дальше его продолжить. Или хотя бы проверить на правильность. Синтаксические ошибки я и сам вижу(где не хватает фигурной скобки, или не ту цифру поставил). Извиняюсь, но уже надоели эти разговори в пустую, сколько можно ходить около. Хочется конкретики услышать, например: вставь этот оператор, или здесь нужно что бы было так. Не хочу никого обижать, но так получается. 

Автор: djamshud 1.6.2010, 20:45
Код за вас писать не буду, но расскажу, как эта костыльная задача решается. Все очень просто.

1. Делается рекурсивная функция
Код

void find(char const *dirname,int minsize,int maxsize,FILE *out);

2. В ней открываете директорию (man 3 opendir) и читаете друг за дружкой все файлы в ней (man 3 readdir).
3. Если это обычный файл, смотрите его размер (man 3 stat), сравниваете с minsize и maxsize; условие проходит - пишите имя файла в out (man 3 fprintf). Если это директория, отправляетесь в рекурсию (man 7 рекурсия).
4. В main читаете аргументы командной строки и передаете их в эту функцию.
5...
6. PROFIT

//int minsize,int maxsize,FILE *out - можно сделать глобальными.

Добавлено через 53 секунды
>У меня такое впечатление что никто здесь не разбирается в линуксе

Я вам доказал, что разбираюсь в линупсе! Теперь я смогу уснуть спокойно. Фхуууу!

Автор: Фантом 1.6.2010, 21:08
Цитата(eu8cc @  1.6.2010,  18:22 Найти цитируемый пост)
Извиняюсь, но уже надоели эти разговори в пустую, сколько можно ходить около. Хочется конкретики услышать, например: вставь этот оператор, или здесь нужно что бы было так. Не хочу никого обижать, но так получается.  

Хм... а Вы не задумывались над тем, что пытаться просить кого-то Вам помочь, не удосужившись хотя бы проверить свой код на синтаксическую корректность, несколько неприлично?

Автор: eu8cc 1.6.2010, 22:23
Большое спасибо djamshud за разъяснения. 

Автор: nickless 2.6.2010, 22:52
Модератор: Перенесено из http://forum.vingrad.ru/forum/Linux-Unix-common-questions.html

Автор: eu8cc 7.6.2010, 08:13
Цитата(djamshud @  1.6.2010,  20:45 Найти цитируемый пост)
1. Делается рекурсивная функцияБез подсветки1:void find(char const *dirname,int minsize,int maxsize,FILE *out);highlightSyntax('nocolor_jFiNzB','nocolor');2. В ней открываете директорию (man 3 opendir) и читаете друг за дружкой все файлы в ней (man 3 readdir).3. Если это обычный файл, смотрите его размер (man 3 stat), сравниваете с minsize и maxsize; условие проходит - пишите имя файла в out (man 3 fprintf). Если это директория, отправляетесь в рекурсию (man 7 рекурсия).4. В main читаете аргументы командной строки и передаете их в эту функцию.



Просмотрите, я правильно записал?

Код

int minsize;
        int maxsize;
        FILE *out;
        int i=0;
        
        void find(char const *dirname,int minsize,int maxsize,FILE *out);
        {
          DIR *dr=opendir (const char *dirname);  
          if (dr==NULL)
           {
             fprintf(stderr,"Невозможно открыть директорию \"%s\"",dirname);
             fclose(f);
             errno = ENOENT;
             perror(", ");
             return -1; exit(1);
           }
           
           struct dirent *dt;
           while((dt=readdir(dr)))
           {
                if(dt->d_type=DT_DIR) find;
                if(dt->d_type=DT_REG)
                {
                if(((dt->st_size)>minsize) $$ ((dt->st_size)<maxsize))) 
                {
                  fprintf(f,"%-40s %-10jd %s\n",filename, (intmax_t) dt->st_size);
                  i=i+1;
                }
                }
           }        
        }


Добавлено @ 08:22
немного подправил

Код

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <ftw.h>
#include <sys/stat.h>
#include <time.h>
#include <stdint.h>

int minsize;
int maxsize;
FILE *out = NULL;
int i=0;
void find(char const *dirname,int minsize,int maxsize,FILE *out);
{
  DIR *dr=opendir (const char *dirname);  
  if (dr==NULL)
         {
     fprintf(stderr,"Невозможно открыть директорию \"%s\"",dirname);
     fclose(out);
     errno = ENOENT;
     perror(", ");
     return -1; exit(1);
   }
   
   struct dirent *dt;
   while((dt=readdir(dr)))
   {
        if(dt->d_type=DT_DIR) find;
        if(dt->d_type=DT_REG)
        {
            if(((dt->st_size)>minsize) $$ ((dt->st_size)<maxsize))) 
            {
              fprintf(out,"%-40s %-10jd %s\n",filename, (intmax_t) dt->st_size);
              i=i+1;
            }
        }
   }
return 0;   
}
int main (int argc,char* argv[])
{
  
    if (argc != 5)
    {    
        fprintf(stderr,"Не все параметры заданы\n");
        errno = EINVAL; //invalid arguments
        perror(argv[0]);
        printf("формат: нач_размер кон_размер папка имя_файла\n");
        return -1;    
    }    
    out = fopen (argv[4],"w+");    
    if ( out == NULL)
    {
        printf("NULL\n");
        fprintf(stderr,"Ошибка создания файла \"%s\"",argv[4]);
        perror(", ");
        return -1;
    }    
    DIR *dr = opendir(argv[3]);    
    if (dr == NULL)    
    {
        fprintf(stderr,"Невозможно открыть директорию \"%s\"",argv[3]);
        fclose(out);
        errno = ENOENT;// no such file or directory
        perror(", ");
        return -1;
    }
    minsize = atol(argv[1]);
    maxsize = atol(argv[2]);
    dirname = argv[3]
    find(*dirname,minsize, maxsize, FILE *out);
    printf ("Число просмотренных файлов равно %d\n", i);
    closedir(dr);
    fclose(out);
    return 0;
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)