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


Автор: Xonxt 21.11.2007, 20:57
Здрасьте smile

Пишу небольшую программу. Она должна получить из командной строки имя файла либо папки и в первом случае прост овывести его параметры, а во твтором: отобразить нечто похожее на дерево каталогов.

Код:
Код

#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

void attributs(struct stat f_st,char *f_name)
{    
    printf("%s\t\t\t%d\n",f_name, f_st.st_size);    
    return;
}
    
void directory(char *f_dir_name)
{    
    struct stat f_dir_st;
    struct dirent *f_directp;
    DIR *f_dirp;
    
    int f_status;
    stat(f_dir_name,&f_dir_st);
    attributs(f_dir_st,f_dir_name);
    
    f_dirp = opendir(f_dir_name);
    f_directp = readdir(f_dirp);
    
    while(f_directp = readdir(f_dirp))
    {
        chdir(f_dir_name);
        stat(f_directp->d_name,&f_dir_st);
        
        if(S_ISREG(f_dir_st.st_mode))
        {
            attributs(f_dir_st,f_directp->d_name);
        }
        else if(S_ISDIR(f_dir_st.st_mode))
        { 
            chdir(f_directp->d_name);
            directory(f_directp->d_name);
            chdir("./..");
        }
    }
    return;
}
    
int main(int argc,char *argv[])
{
    struct stat st;
    struct dirent *directp;
    DIR *dirp;
    int status;
    
    printf("Name\t\t\tSize\n");
    
    if(argc!=2)
    {
        printf("Ошибка передачи параметров\n");
        _exit(1);
    }
    
    if(stat(argv[1],&st)!=0)
    {
        printf("Ошибка! Такого файла не существует\n");
        _exit(1);
    }
    
    if(S_ISREG(st.st_mode))
    {
        attributs(st,argv[1]);        
        _exit(0);
    }
    else if (S_ISDIR(st.st_mode))
    { 
        chdir(argv[1]);
        directory(argv[1]); 
    }
    _exit(0);
}


При первой же попытке программы зайти в какую либо папку, выдается "ошибка сегментирования".

Где я ошибся? Заранее спасибо.

Автор: MAKCim 21.11.2007, 22:38
Код

#include <fcntl.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
void attributs(struct stat f_st,char *f_name)
{    
    printf("%s\t\t\t%d\n",f_name, f_st.st_size);    
    return;
}
    
void directory(char *f_dir_name)
{    
    struct stat f_dir_st;
    struct dirent *f_directp;
    DIR *f_dirp;
    int f_status;
    strcpy(name, f_dir_name);
    stat(name,&f_dir_st);
    attributs(f_dir_st,name);
    
    if ((f_dirp = opendir(name)) == NULL)
        return 0;
    chdir(name);
    
    while(f_directp = readdir(f_dirp))
    {
        if (!strcmp(f_directp -> d_name, ".") || !strcmp(f_directp -> d_name, ".."))
            continue;
        stat(f_directp->d_name,&f_dir_st);
        
        if(S_ISREG(f_dir_st.st_mode))
        {
            attributs(f_dir_st,f_directp->d_name);
        }
        else if(S_ISDIR(f_dir_st.st_mode))
        { 
            directory(f_directp->d_name);
        }
    }
    closedir(f_dirp);
    chdir("..");
}
    
int main(int argc,char *argv[])
{
    struct stat st;
    struct dirent *directp;
    DIR *dirp;
    int status;
    
    printf("Name\t\t\tSize\n");
    
    if(argc!=2)
    {
        printf("Ошибка передачи параметров\n");
        _exit(1);
    }
    
    if(stat(argv[1],&st)!=0)
    {
        printf("Ошибка! Такого файла не существует\n");
        _exit(1);
    }
    
    if(S_ISREG(st.st_mode))
    {
        attributs(st,argv[1]);        
        _exit(0);
    }
    else if (S_ISDIR(st.st_mode))
    { 
        directory(argv[1]); 
    }
    _exit(0);
}

совет на будущее
делай проверки после вызова библиотечных функций  smile 

Автор: Xonxt 21.11.2007, 22:42
Ув. MAKCim, Ваше внесение исправлений в код к решению проблемы с ошибкой сегментирования не привело. Думаем дальше..

Методом брутфорсного тестирования удалось выяснить, что при таком, к примеру, дереве каталогов:

Код

/root/
----/root/dir1/
--------/root/dir1/dir4/
--------/root/dir1/dir5/
------------/root/dir1/dir5/dir6
------------/root/dir1/dir5/dir7
--------/root/dir1/dir8/
----/root/dir2/
--------/root/dir2/dir9/
--------/root/dir2/dir10/
----/root/dir3/

ошибка появляется сразу же после 25 строки
Код
f_dirp = opendir(f_dir_name);


Ребят, неужели никаких соображений?(
Это нужно уже на завтра :(

Автор: MAKCim 21.11.2007, 22:53
Xonxt, 
да не может быть
проверь еще раз
ты код правильно скопировал?

Автор: Xonxt 21.11.2007, 22:56
Обижаешь...

Программа работает отлично, если в рассматриваемой папке нет других папок, а только файлы. А если есть другие папки (как в примере дерева каталогов в моём предыдущем сообщении), то на них вылетает ошибка.

Либо дело в разных операционках. У меня вот Suse 10.2

Добавлено через 5 минут и 48 секунд
Гм.. пардон.
Скопировал код еще раз - заработало.

Дивны дела твои, Юникс (( Спасибо большое smile

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