在C语言中操作备忘录的方法
一:fopen()中的第二参数(模式参数)的格式详解
可用来组合的字符有:r,w,a,t,+,b,它们分别代表的意义为:
r: read;
w: write;
a: append;
t: text;
+: refresh;
b: binary;
它们可以拿来互相组合,构成不同的打开模式,比如常见的有:
"r" 打开文件用于读,若文件不存在,则出错fopen返回NULL,初始位置指针位于文件第一个字节(亦即第一个字符)上。
"w" 打开文件用于写,若文件不存在,则按所给文件名建立新文件;若文件存在,则要清除原文件中的所有内容,并将初始位置指针置于文件第一个字节处(其实在这儿就是EOF)上。在以"w"模式打开的文件中,也不可以做任何如fgetc()之类的读取操作,否则后果不可预计。
"a" 打开文件用于追加内容,若文件不存在,则按所给文件名建立新文件,然后追加;若文件存在,则将位置指针置于文件末尾,也就是EOF上,以下程序可验证:
FILE * fp=fopen("4.txt","a");
if(fp==NULL)
{
printf("Open file failed!/n");
return -1;
}
if(fgetc(fp)==EOF)
{
printf("EOF");
}
它的输出是EOF。我想系统内部的操作应该是判断是否为EOF,如果是,则覆盖之,再在文件末尾插入一个EOF,若不是,则从下一个字节写起。当然上面的代码实际不可取,因为以"a"方式打开的文件,你在并没有转移位置指针的情况下就fgetc(),而fgetc()完了会将位置指针移到下一个字节,可是当前已是EOF,下一个字节将移往何处呢?上面我想到了转移位置指针,但我拿 rewind()测试时:
FILE * fp=fopen("4.txt","a");
if(fp==NULL)
{
printf("Open file failed!/n");
return -1;
}
rewind(fp);
if(fgetc(fp)==EOF)
{
printf("EOF");
}
仍然要输出EOF,可见rewind()在以"a"模式打开的文件流中没有起作用,然后我将rewind()那行换为fseek(fp,0L,SEEK_SET);仍然要输出EOF,可见以"a"模式打开的文件只能在文件末尾追加,且最好不要在其中做任何读取操作,这个可不太好。
"ra" "rw" "aw" 之类的组合不会引起编译错误(VC6.0中),但是意义本来就相悖,也不会这么用。
"r+" 打开文件以读和写,若文件不存在,则发生错误,若文件存在,则打开之,初始位置指针指向文 件第一个字节,此时你使用fputc()向文件输入字符,会发现你输入的字符把原文件位置指针指 向的字符覆盖掉了(而不是插入),同样,每个fputc()完了要将当前位置指针后移一个字节。如 果你认为指定了那样的打开模式,你就可以交错的进行读取和插入操作的话,那你就错了,C语言标准制定时,为了保持与过去不能同时进行读写操作的程序的向下兼容性,一个输入操作后面不能直接跟一个输出操作,反之亦然,如果要同时进行输入和输出操作, 必须在其间插入 fseek()操作,fseek( f, 0L, SEEK_CUR);以上关于r+的这段内容来自<<C缺陷与陷阱>>一书,但 我从网上看到文章说"如果要同时进行读写操作,必须在读写操作交换的地方插入fseek()、fgetpos()与fsetpos(),fflush()这三组的函数中的一个。"比如:
fpos_t pos;
FILE *f;
... ...
fgetpos( f, &pos ); //use these two lines
fsetpos( f, &pos ); // replace fseek(f, 0L, SEEK_CUR);
... ...
像这种问题真称得上陷阱,幸亏早先知道了,要不出这么个bug,可折腾死人了。
"w+" 打开文件以读和写,若文件不存在,则创建之,若存在,则要清空原来的内容,从文件头写起。其实我觉得"w+"与"w"无甚区别。
"a+" 打开或创建文本文件用于更新,写文件时追加到文件末尾。也应该与"a"没区别吧。
如果在上述访问模式之后再加上b,如"rb","w+b"等,则表示对进制文件进行操作。
二:关于fclose()
大家都知道fclose()是用来关闭打开的文件流的,它断开由fopen()函数建立的文件指针和外部名之间的连接,交释放文件指针以供其它文件使用。因为大多数系统都限制了一个程序可以同时打开的文件数,所以,当文件指针不再需要时就应该释放,这是一个好的编程习惯。对输出文件执行fclose()还有另一个原因:它将缓冲区中由fputc()正在收集的输出写入到文件中。当程序正常终止时,程序会自动为每个打开的文件调用fclose()函数。
三:高手们给我做的补充:
(1):fclose()会在文件尾加一个EOF标志.
(2):fclose 操作后,
才会将所有的输入内容从缓冲中真正的写到文件中 ...
这些内容不仅仅是 fputc 函数写的,
还有其他函数 ...
(3): 可加的后缀为t、b。加b表示文件以二进制形式进行操作,t没必要使用
例:┌──────────────────┐
│#include<stdio.h> │
│main() │
│{ │
│ FILE *fp; │
│ fp=fopen("C://WPS//WPS.EXE","r+b");│
└──────────────────┘
其实在系统中是有个定义默认打开方式为文本方式还是二进制方式的常量,一般默认为文本方式,你如果重新定义了那个常量,就需要用到 t 了。
四:写这个总结的原因
因为我在CSDN上看到一个贴子问:读取TXT文件之后,怎么实现在每一行的前面加上一串相同的字符串?
我想这还不简单啊,打开文件检测下'/n'直接插不就得了,可往下一看,大牛们的回复真复杂:
///////////////////////////////////////////////////////////////////////////////////
UPCC(杂食动物) ( ) 信誉:118 2006-8-11 19:41:41 得分: 0
读出来后,fgets(str);在str前面加字符串,写入临时文件,操作完成后,删除原来的文件,把临时文件的名字改为原来的名字。
///////////////////////////////////////////////////////////////////////////////////
jixingzhong(瞌睡虫:选择了远方,只顾风雨兼程!) ( ) 信誉:102 2006-8-11 20:19:54 得分: 0
int main()
{
FILE *fp, *fp2;
char s[256], *scat=" Baby!/n"; //scat 是要连接上去的字符串
fp = fopen("test.txt", "r"); //源文件
fp2 = fopen("test2.txt", "w"); //目标文件
fgets(s, 256, fp);
while(!feof(fp))
{
s[ strlen(s)-1 ] = '/0'; //读取的行末尾的 回车换行符号 给去掉
fputs(strcat(s, scat), fp2); //连接并写文件
fgets(s, 256, fp);
}
fputs(strcat(s, scat), fp2);
fclose(fp);
fclose(fp2);
system("PAUSE"); //有必要的话重命名 test2.txt 为原来的文件就 OK
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////
tailzhou(尾巴) ( ) 信誉:100 2006-8-11 21:10:34 得分: 0
改了下斑竹的,不需要strcat连接.
int main()
{
FILE *fp, *fp2;
char s[256]="Baby"; //假设是要连接上去的字符串
int idx=strlen(s);
fp = fopen("test.txt", "r"); //源文件
fp2 = fopen("test2.txt", "w"); //目标文件
fgets(s+idx, 256-idx, fp);
while(!feof(fp))
{
fputs(s,fp2);
fgets(s+idx, 256-idx, fp); //还可以把s+idx,256-idx作成变量,就不用每次都计算
}
fclose(fp);
fclose(fp2);
system("PAUSE"); //有必要的话重命名 test2.txt 为原来的文件就 OK
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////
wiali(维埃里) ( ) 信誉:99 2006-8-12 1:06:21 得分: 0
fgets(s+idx, 256-idx, fp);
--赞一个
/////////////////////////////////////////////////////////////////////////////////////////
我靠,有这么复杂吗?我心里没底了,得,我把文件操作认真看一遍,再来做这个题目,现在还没认真看完呢我就知道了,他这个问题还就得如大牛们那么做哈,没想到C语言把一个简单的字符插入搞得如此之复杂,也许有什么原因吧。唉,我的C语言功底就是如此不济,但愿看完这遍有点成效。
关于文件操作别的函数,用到了再总结。
本文地址:http://www.45fan.com/a/question/71626.html