我已经写了这段代码
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
char *list[20],*story[100];
FILE*listfile;
FILE*infile;
FILE*outfile;
int check(char*string)
{
int i=0;
while(list[i]!=NULL)
{
if(strcmp(string,list[i])==0){return 1;};
i++;
};
return 0;
};
void print_d(int d){ printf(" debug %d ",d);};
int main(int argc,char**argv){
assert(argc==4);
printf("hello \n");
//assigning the file pointers in their respective modes
printf("%s %s %s ",argv[1],argv[2],argv[3]);
listfile=fopen(argv[1],"r");
print_d(12);
infile=fopen(argv[2],"r");
outfile=fopen(argv[3],"w");
print_d(0);
int i=0; /* the infamous 'i' */
while(1)
{
if(feof(listfile)!=0)
{ break;};
list[i]=malloc(sizeof(char [15]));
fscanf(listfile,"%s[^\n]",list[i]);
i++;
}
i=0;
print_d(1);
while(1)
{
if(feof(infile)!=0)
{ break;};
story[i]=malloc(sizeof(char [25]));
fscanf(infile,"%s",story[i]);
i++;
}
fclose(infile);
fclose(listfile);
i=0;
print_d(2);
while(1)
{
if(check(story[i])==1)
{ fprintf(outfile,"%s","censored");}
else
{
fprintf(outfile,"%s",story[i]);
};
};
print_d(3);
fclose(outfile);
i=0;
while(list[i]!=NULL)
{ free(list[i]);};
return 0;
}
随后出现以下问题
[1]输出是您好,然后是段错误
这就是事情变得有趣的地方
如果我修改
printf(“%s%s%s”,argv [1],argv [2],argv [3]);
至
printf(“%s%s%s \ n”,argv [1],argv [2],argv [3]);
输出是“ hello”,后跟文件的三个名称,然后是段错误。
在用户danfuzz指出我应该将print_d调试更改为print到stderr之后(我确实这样做了).. debug打印现在可以正常工作了。所以我想一个更好的问题是,为什么会首先发生这种情况并采取措施防止这种情况发生事情发生了吗?
对于经验丰富的程序员来说,这似乎是一个微不足道的问题,但是请注意,较早的版本(上面的代码中的那个)在seg错误之前无法打印出任何消息,导致我断定在/ open的命令行部分发生了某些事情文件。
一些观察,
您应该阅读fflush(stdout)
,因为它会帮助您进行调试,
void print_d(int d)
{
printf(" debug %d ",d); fflush(stdout);
};
您分配给char指针,list[20]
和数组story[100]
,但是有循环(以臭名昭著的“ i”索引),可以轻松地走出列表或故事的结尾。
您试图打开文件的文件名argv[2]
和argv[3]
,一个作为读取其他如写,改变这些线以下,
printf("%s %s %s ",argv[1],argv[2],argv[3]); fflush(stdout);
if( !(listfile=fopen(argv[1],"r")) )
{
printf("cannot open %s\n",argv[1]); fflush(stdout);
return(1);
}
print_d(1);
if( !(infile=fopen(argv[2],"r")) )
{
printf("cannot open %s\n",argv[2]); fflush(stdout);
return(2);
}
print_d(2);
if( !(outfh=fopen(argv[3],"w+")) ) //notice the "w+" to create missing file
{
printf("cannot open %s\n",argv[3]); fflush(stdout);
return(3);
}
print_d(3);
现在文件已正确打开,因此将debug print_d参数更改为增加的数字顺序,以便您可以顺序发现哪些内容,并且由于使用了计数器,因此可以使用for(;;)
循环,
int check(char*string)
{
int i;
for(i=0; list[i]!=NULL; i++)
{
if(strcmp(string,list[i])==0){return 1;};
};
return 0;
};
更改循环以成功读取两个文件,
for(i=0; i<20; ++i)
{
if(feof(listfh)!=0) { break; };
list[i]=malloc(sizeof(char [15]));
fscanf(listfh,"%s[^\n]",list[i]);
}
fclose(listfh);
debug(4);
和,
for(i=0; i<20; ++i)
{
if(feof(infh)!=0) { break; };
story[i]=malloc(sizeof(char [25]));
fscanf(infh,"%s",story[i]);
}
fclose(infh);
debug(5);
现在,只需对循环进行简单的更改即可扫描故事,检查检查结果(注意!),因此我们避免比较和打印空指针(您遇到的另一个问题),
for(i=0; i<100 && (story[i]); ++i)
{
if(check(story[i])==1)
{
fprintf(outfh,"%s","censored"); fflush(outfh);
}
else
{
fprintf(outfh,"%s",story[i]); fflush(outfh);
};
};
但是请注意,您确实不需要将故事读入一个数组中,您可以一次阅读一行,然后将这两个循环打印结合在一起,就可以扫描任意大的文件,而无需分配大量空间,
for(i=0; 1; ++i)
{
if(feof(infh)!=0) { break; };
story[0]=malloc(sizeof(char [25]));
fscanf(infh,"%s",story[0]);
if(check(story[0])==1)
{
fprintf(outfh,"%s","censored"); fflush(outfh);
}
else
{
fprintf(outfh,"%s",story[0]); fflush(outfh);
};
}
fclose(infh);
fclose(outfh);
您还需要确保只释放分配的行,
for(i=0; list[i] && list<20; i++)
{
free(list[i]);
}
这应该可以解决您的问题。
添加一个usage()函数,
void usage(char*progname)
{
printf("need 3 files\n");
printf("%s <restricted> <story> <censorted>\n",progname);
}
叫它
if( argc < 4 )
{
usage(argv[0]);
return 0;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句