C语言中更新文件

时间:2023-01-19 18:11:18

     在许多文件处理应用中,你可能对创建一个新的文件不感兴趣,但是对修改已存在的文件感兴趣。修改文件的过程称为更新文件。这不像想象的那么简单。

     在大多数系统中,如果一个文件因为输入而打开着,再要为输出打开它是不合法的。根据文件在特定的系统中实现的方式不同,fopen的调用可能失败或者破坏文件中的内容。

     更新文件最普遍的方法是:先写新数据到临时文件中,然后更新文件的整个内容之后,用临时文件替换原有文件。因此,如果希望编写程序来更新已有的文件,该程序下面的步骤组成:

     1)打开原有的输入文件;

     2)打开一个不同名的临时输出文件;

     3)把输入文件复制到临时文件,执行希望的更新操作;

     4)关闭两个文件;

     5)删除原始文件;

     6)用原始文件的名称重命名临时文件;

     为了实现这个策略,需要用到3个来自stdio.h接口的函数:tmpnam、removerename

     尽管你可以为临时文件*地选择名称,但是在stdio.h接口中有一个tmpnam函数可以生成临时文件。临时文件的约定,随一台机器的不同而不同。调用tmpnam(null)函数返回一个适合机器的临时文件名。因此,可以使用下面的编码创建和打开一个新的临时文件:

      temp = tmpnam(NULL);

      outfile = fopen(temp,"w");

     为了删除一个文件,只需要调用remove(name)就可以了,其中的name是该文件的名称。重命名文件也很简单,可以通过调用rename(old name, new name)函数来实现。

与ANSI库中的许多函数一样,remove和rename在正确时返回0,在失败时返回非0值。尽管你会遇到把这些函数只是看成出来过程的代码,但是通过它们的返回值来确保操作的成功是比较安全的。

     这3个函数可以使用我们编写一个使用CopyRemovingComments函数从文件中删除注释的程序,如下所示:

void CopyRemovingComments(FILE* infile,FILE* outfile)
{
int ch,nch;
bool commentFlag;

commentFlag = false;
while((ch = getc(infile))!=EOF){
if (commentFlag)
{
if (ch == '*')
{
nch = getc(infile);
if (nch == '/')
{
commentFlag=false;
}
else
{
ungetc(nch,infile);
}
}
}else{
if (ch == '/')
{
nch = getc(infile);
if (nch == '*')
{
commentFlag=false;
}
else
{
ungetc(nch,infile);
}

}

if (!commentFlag)
{
putc(ch,outfile);
}
}

}

}

void main()
{
string filename,temp;
FILE *infile,*outfile;

printf("This program removes comments from a file.\n");
while(true){
printf("File name: ");
filename = getline();
infile = fopen(filename,"r");
if(infile != NULL)
break;
printf("File %s not found -- try again.\n",filename);
}

temp = tmpnam(NULL);
outfile = fopen(temp,"w");
if (outfile == NULL)
{
Error("Can't open temporary file.");
}
CopyRemovingComments(infile,outfile);
fclose(infile);
fclose(outfile);
if (remove(filename)!=0 || rename(temp,filename)!=0)
{
Error("Unable to rename temporary file.");
}

}