C语言 文件的输入与输出

1.C提供了两种访问文件的途径: 二进制模式和文本模式

二进制中: 程序可以访问文件的每个字节, 文本模式中,程序所见的内容与实际内容不同,以二进制模式打开时:rebcca clutched the\r\n; 以文本模式打开时:rebecca clutched the\n 2.如何用标准I/O读取文件和统计文件中的字符数:

#include <stdio.h>
#include <stdlib.h>//提供exit()原型
int main()
{
int ch;   /// 读取文件时,储存每个字符的地方
FILE *fp;   //文件指针
unsigned long count = 0;
if ( argc != 2 )
{
printf("Usage: %s filename\n",argv[0]);
exit(EXIT_FAILURE); ///EXIT_FAILURE用于表明结束程序失败
}
if ( ( fp = fopen(argv[1], "r")) == NULL )
{
printf("Can't open %s\n",argv[1]);
exit(EXIT_FAILURE);//
}
while ( ( ch == getc(fp) ) != EOF )
{
putc(ch, stdout);  //putchar(ch)相同
//stdout作为与标准输出相关联的文件指针,
count++;
}
fclose(fp);
printf("File %s has %lu characters\n",argv[1], count);
return 0;
}

exit函数: 关闭所有打开的文件并结束程序,正常结束的程序传递为0,异常结束的程序传递非0值。标准要求0 或 宏EXIT_SUCCESS用于表明成功结束程序

一般情况下 return 0与exit(0)效果相同,但在递归函数中exit()仍会终止程序,return 则是把控制权交给上一层递归 这两个还有一个区别是:即使在其他函数中(除main外)调用exit()函数也会结束整个程序 fopen()函数:使用fopen函数打开文件,第一个参数是待打开文件的名称,更确切的说是一个包含该文件名的字符串的地址。第二个参数是一个字符串,指定待打开文件的模式。 程序成功打开文件后,fopen()将返回文件指针,其他I\O函数可以用这个指针指定该文件。文件的指针类型是指向FILE的指针,FILE是一个定义在stdio.h中派生类型。文件指针fp并不指向实际文件,它指向一个包含文件信息的数据对象,其中包含很多。。。 以下为一些模式: “r”: 以读模式打开文件 “w”: 以写模式打开文件把现有文件的长度截为0,如果文件不存在,则创建一个新文件 “a”: 以写模式打开文件,在现有文件末尾添加内容,如果文件不存在,则创建一个新文件 “r+”: 以更新模式打开文件(即可以读写文件) “w+”: 以更新模式打开文件(即读和写),在现有文件的末尾添加内容,如果文件不存在则创建一个新文件 “a+”: 以更新模式打开文件(即读和写),在现有文件的末尾添加内容,如果文件不存在则创建一个新文件;可以读整个文件,但是只能从末尾添加内容 “rb”,“wb”,"ab","rb+","r+b","wb+","w+b","ab+","a+b": 与上一个模式类似,但是以二进制模式而不是文本模式打开文件 “wx”,"wbx","w+x","wb+x","w+bx": 类似非x模式,但是如果文件已存在或以独占模式打开文件夹,则打开文件夹失败 C11新增的带x字母的写模式,比传统的写模式具有更多特性,第一:如果以传统的写模式打开一个现有文件,fopen()会把该文件的长度截为0,这样就丢失了该文件的内容,但是使用带x字母的写模式,即使fopen()操作失败,原文件的内容也不会被删除。第二,x的独占特性使得其他程序或线程无法访问正在被打开的文件

.getc()和putc()函数

要告诉getc()和putc()函数使用哪一个文件,下面这条语句意思:从标准输入中获取一个字符 ch = getchar(); 然而下面这条语句的意思是: 从fp指定的文件中获取一个字符: ch = getc(fp); 与此类似,下面语句的意思是 把字符ch放入FILE指针fpout指定的文件中: putc(ch, fpout);

.文件结尾

当getc()函数在读取一个字符时发现是文件结尾,它将返回一个特殊值EOF。 为了避免读到空文件,应该使用入口条件循环(不是do while)进行文件输入。鉴于getc的设计,程序应该在进入循环体之前先尝试读取。如下面的设计所示:

int ch;    //int类型变量储存EOF
FILE *fp;
fp = fopen("wacky.txt","r");
ch = getc(fp);   //   获取初始输入
while ( ch != EOF )
{
putchar(ch); // 处理输入
ch = getc(fp);  // 获取下一个输入
}
.fclose()函数

fclose(fp)函数guanbifp指定的文件,必要时刷新缓冲区。若成功关闭,fclose()函数返回0,否则返回EOF: if ( fclose(fp) != 0 ) printf("Error in closing file %s\n",argv[1]);

.指向标准文件的指针:stdio.h把三个文件指针与三个标准文件关联,C程序会自动打开这三个标准文件:

标准文件 文件指针 通常使用的设备
标准输入 stdin 键盘 标准输出 stdout 显示器 标准错误 stderr 显示器

用一个程序实例创建一个新文件,并写入内容 文件压缩程序的原理: 把一个文件中选定的数据拷贝到另一个文件中,该程序同时打开了两个文件,以“r” 模式打开一个,以“w”模式打开一个,该程序以保留每三个字符中的第一个字符的方式压缩第一个文件的内容。最后,把压缩后的文本存入第二个文件。第二个文件的名称是第一个文件名加上.red后缀。使用命令行参数,同时打开多个文件,以及在原文件名后面加上后缀,都是相当有用的技巧。如下:

#include <stdio.h>
#include <stdlib.h> //提供exit(
#include <string.h> // 提供strcpy(),stract()原型
#define LEN 40
int main()
{
FILE *in,*out;//声明两个指向FILE的指针,因为该程序同时打开了两个文件
int ch;
char name[LEN];//储存输出文件名
int count = 0;
//检查命令行参数
if ( argc < 2 )
{
fprintf(stderr , "Usage: %s filename\n",argv[0]);
exit(EXIT_FAILURE);
}
//设置输入  *** 不能用else if 
if ( (in = fopen(argv[1], "r")) == NULL )  //
{
fprintf(stderr,"I couldn't open the file\"%s\"\n",argv[1]);//I couldn't open the file存放进argv[1]中,并发送argv[1]中的信息到指定的stderr文件||  程序利用stderr指针把错误消息发送至标准错误
exit(EXIT_FAILURE);
}
//设置输出
strncpy(name, argv[1], LEN - 5);//拷贝文件名
//strncpy  更谨慎的选择,因为 该函数的第三个参数指明可拷贝的最大字符数。
name[LEN-5] = '\0';//LEN - 5.red后缀和末尾的空字符预留了空间
}
strcat(name,".red");   // 在文件名后添加.red
//name中的第一个空字符'0'在调用strcat函数时,被.red覆盖,生成eddy.red
if ( (out = fopen(name, "w") ) == NULL ) // 是否成功的以写模式打开名为eddy.red的文件
//这个步骤在一些环境中相当重要,因为像strang.c.red这样的文件名可能是无效的
{
fprintf(stderr,"Can't create output file.\n");
exit(3);//非正常运行导致退出程序 
}
//拷贝数据
while ( ( ch = getc(in)) != EOF )
{
if ( count++ %3 == 0 )
putc(ch, out); // 打印三个字符中的第一个字符
//收尾工作
if ( fclose(in) != 0 || fclose(out) = 0 
fprintf(stderr, "Erroe in closing files\n");
return 0;
}

int main(int argc, char** argv)
第一个参数int argc,表示命令行参数的个数。第二个参数char *argv[]是一个指向命令行参数的指针数组,每一参数又都是以空字符(null) 结尾的字符串。第一个字符串,亦即argv[0]指向的,(通常)是该程序的名称。argv中的指针列表以NULL指针结尾(即argv[argc]为NULL)。 argv[1]为DOS命令行后执行命令的第一个字符串,argv[2]为执行程序名后的第二个字符串


猜你喜欢

转载自blog.csdn.net/teropk/article/details/79855966