【发布时间】:2019-04-09 05:09:08
【问题描述】:
我正在为编程课做一个作业。
该程序应该:
- 从命令行接收字符串。
- 打开当前目录并循环浏览其条目,
并仅在其名称以 我从 CMD 传递的字符串。 - 如果这些条目是常规文件,
我需要计算除空格以外的所有字符,
并计算以 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 传递的模式开头的第一个条目,并正确评估它,但随后
当在第二个条目上调用 stat 时,会导致 seg fault 11。
如果我注释掉 lstat,所有符合条件的条目都会被识别,即使没有计算我也无法测试它是否是没有 lstat 的常规文件...
是什么原因造成的,过去两个小时我一直在尝试一些东西,请帮助我,谢谢!
编辑:
我发现了问题,基本上我正在工作的目录有可执行文件的二进制文件。
原来二进制文件被认为是普通文件,所以当程序打开它解析它时,它解析了一个导致临时变量缓冲区溢出的长字符串。我认为这些文件是二进制文件,并与常规文件分开。
【问题讨论】:
-
旁白:
while((fscanf(file,"%s",temp))!=EOF)会更好while((fscanf(file,"%s",temp))==1) -
Adonai,
char temp[100]; ... fscanf(file,"%s",temp)是 100 或更长的“单词”的问题。如果file == NULL,fscanf(file...也是一个问题。 -
@chux 为什么如果文件为空会出现问题?顺便说一句,更改缓冲区大小并没有解决问题,即使空文件有问题,事实是我什至在打开文件之前调用了 stat,所以这不是问题:/
-
@chux 无论如何,我检查了是否有任何文件为空...没有人是。段错误显然是由于另一个原因而发生的。扩大缓冲区大小甚至没有帮助。
-
代码不检查来自
lstat的返回值。错误检查至关重要,尤其是在出现问题时。有原因的优雅程序退出使开发过程中的生活更轻松(在发布版本中更是如此)。
标签: c operating-system filesystems