lstat函数引起的意外段错误

时间:2018-11-05 19:48:29

标签: c operating-system filesystems

我正在为编程课分配作业。
该程序应该:

  1. 从命令行接收字符串。
  2. 打开当前目录并循环浏览其条目,
    并仅在名称以开头的情况下分析条目 我从CMD传递的字符串。
  3. 如果这些条目是常规文件,
    我需要计算除空格以外的所有字符,
    并计算以a / 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传递的模式开头的第一个条目,并对其进行了正确评估,但随后
在第二个条目上调用该统计信息时,将导致段错误11。

如果我注释掉lstat,即使没有计算,我也无法测试是否是不带lstat的常规文件,所以所有符合条件的条目都会被识别...
是什么原因引起的,过去两个小时我一直在尝试一些东西,请帮助我,谢谢!

编辑:

我发现了问题,基本上我正在使用的目录具有可执行文件的二进制文件。

原来,二进制文件被认为是常规文件,因此当程序打开对其进行解析时,它会解析一个长字符串,这会导致temp变量上的缓冲区溢出。我以为这些文件是二进制文件,与常规文件分开了。

1 个答案:

答案 0 :(得分:1)

  

lstat函数引起的意外段错误

由于代码其他部分的行为不确定,因此我们不知道段错误是由lstat引起的。包含lstat确实揭示了一个问题,但真正的原因可能在其他地方。


代码有麻烦,但是在各个地方都缺少错误检查。 @Weather Vane

检查函数返回值

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);
  }

代码出租车当然不会退出,而是以其他方式处理错误。

次要:我使用宽度类型来计算字符。