gpt4 book ai didi

c - 标准输出缓冲问题

转载 作者:太空宇宙 更新时间:2023-11-04 03:52:45 25 4
gpt4 key购买 nike

这段代码我已经写好了

#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] 输出是一个 hello 后跟一个 seg fault

这里是事情变得有趣的地方

如果我修改

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 调试以打印到 stderr(我这样做了)..调试打印现在工作正常。所以我想一个更好的问题是为什么首先会发生这种情况和步骤防止这样的事情发生?

对于经验丰富的程序员来说,这似乎是一个微不足道的问题,但请注意,早期版本(上面代码中的那个)未能在段错误之前打印出任何消息,这让我得出结论,在命令行部分发生了一些事情事情/打开文件。

最佳答案

一些观察,

您应该阅读有关 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);

现在文件可以正确打开,所以将调试 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;
}

关于c - 标准输出缓冲问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19460512/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com