неожиданная ошибка сегмента, вызванная функцией lstat - PullRequest
0 голосов
/ 05 ноября 2018

Я делаю задание для класса программирования.
Программа должна:

  1. получить строку из командной строки.
  2. открыть текущий каталог и просмотреть его записи,
    и анализировать записи, только если их имя начинается с строка, которую я передал из CMD.
  3. если эти записи являются обычными файлами,
    мне нужно сосчитать все символы кроме пробелов,
    и посчитайте количество слов, которые начинаются с / A.

Вот код.

int main(int argc,char* argv[])
{
    if(argc!=2) //ensures at least an argument is passed.
    {
        puts("enter one argument.");
        exit(EXIT_FAILURE);
    }

    DIR* folder; //folder abstraction
    struct dirent* entry; //entry abstraction
    struct stat info; //file's i node info

    FILE* file;
    int total=0,first=0;
    char temp[100];

    int res;

    folder=opendir("."); //i open the directory

    while((entry=readdir(folder))!=NULL) //i cicle through every entry
    {

        res=strncmp(entry->d_name,argv[1],strlen(argv[1]));
        if(res==0) //if entry name begins with string i continue
        {

            lstat(entry->d_name,&info); //i take file info
            if(S_ISREG(info.st_mode)) //i check if it's a regular file
            {
                file=fopen(entry->d_name,"r"); //i open it
                //printf("%s\n",entry->d_name);
                while((fscanf(file,"%s",temp))!=EOF) //i parse it
                {
                    if(temp[0]=='a'|| temp[0]=='A')
                    {
                        first++;
                    }
                    total+=strlen(temp);
                }
                //now i close the file and print all info
                fclose(file);
                printf("%s\nthe number words that start with a/A: %i\n",entry->d_name,first);
                printf("the amount of characters except spaces is %i\n",total);
                total=0;
                first=0;
            }

        }
        //now the process will be repeated for the remaining entries
    }
    return 0;
}

проблема в том, что программа получает первую запись, которая начинается с шаблона, который я передал из CMD, оценивает его правильно, но затем
когда stat вызывается для второй записи, это вызывает ошибку seg 11.

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

РЕДАКТИРОВАТЬ:

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

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

1 Ответ

0 голосов
/ 05 ноября 2018

неожиданная ошибка сегмента, вызванная функцией lstat

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


У кода есть проблемы, но в разных местах отсутствует проверка ошибок. @ Флюгер

Проверка возвращаемых значений функции

folder=opendir(".");
if (folder == NULL) {
  perror("opendir failed);
  exit (EXIT_FAILURE);
}


// lstat(entry->d_name,&info);
if (lstat(entry->d_name,&info)) {
  perror("lstat failed);
  exit (EXIT_FAILURE);
}

file=fopen(entry->d_name,"r");
if (file == NULL) {
  fprintf(stderr, "Unable to open <%s> for reading\n", entry->d_name);
  exit (EXIT_FAILURE);
}

Предельная ширина

// while((fscanf(file,"%s",temp))!=EOF)
while(fscanf(file,"%99s",temp) == 1) {
  if (strlen(temp) == 99) {
    fprintf(stderr, "Maximum length word read, longer ones might exist\n");
    exit (EXIT_FAILURE);
  }

Конечно, вместо выхода, код каб обработает ошибку другим способом.

Незначительный: я использовал типы ширины для подсчета символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...