博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
嵌入式成长轨迹18 【Linux应用编程强化】【Linux下的C编程 下】【标准输入输出】...
阅读量:5010 次
发布时间:2019-06-12

本文共 8146 字,大约阅读时间需要 27 分钟。

 

一   标准输入输出的基本操作

文件控制结构中包含处理文件所需的全部信息,例如文件名、文件当前的读写位置、用于该文件读写的内存缓冲区位置等。打开文件时,系统会在内存中自动建立该文件的控制结构。关闭文件时,文件控制结构被释放。在对文件进行操作之前,要首先获取文件的指针,即指向文件控制结构的指针,后续操作都通过该指针进行。标准输入输出时,有3个比较特殊的文件,它们是:标准输入文件(stdin):一般为键盘;

标准输出文件(stdout):一般为显示器;

标准错误输出文件(stderr):一般为显示器。

1 文件的打开

操作文件之前要打开文件,打开文件主要是在系统中分配一些资源用于保存该文件的状态信息,并获取文件的指针,以后调用其它函数对文件进行读写操作时都要提供这个指针。

2 文件的关闭

  FILE *fopen(const char *filename, const char *modes);
对文件操作完成后,应该关闭文件,进而释放文件所占用的系统资源。文件关闭之后,文件指针将不再有效,用户也就无法通过该指针操作文件。

 int fclose(FILE *fp);

1 /* example1.c */  2 #include 
3 #include
4 int main() 5 {
6 FILE *fp; /* 定义文件指针 */ 7 fp = fopen("./hello.c", "r"); /* 打开文件 */ 8 if (fp == NULL) /* 如果文件打开失败,输出错误信息并退出 */ 9 {
10 printf("Open hello.c failed.\n"); 11 exit(1); 12 } 13 printf("Open file succeed.\n"); 14 fclose(fp); /* 关闭文件 */ 15 return 0; 16 }

3 缓冲区的刷新
刷新操作是指将缓冲区中的数据清除,这项工作可以由fflush或fpurge函数完成。

 int fflush(FILE *fp);

 int fpurge(FILE *fp);
4 缓冲区属性的设置
缓冲区的大小和类型等都可以通过函数来设置,缓冲区的类型有下面三种:

全缓冲:缓冲区被填满后才执行输入输出操作,将数据写入到磁盘文件或输出到用户终端;

行缓冲:缓冲区中填入换行符时,执行输入输出操作;

无缓冲:不对数据进行缓存,标准错误输出stderr一般就是无缓冲的,这可以使错误信息尽快地显示出来。

 

int setvbuf(FILE *fp, char *buf, int mode, size_t size);

_IOFBF、_IOLBF、_IONBF

 

二  非格式化输入输出
非格式化输入输出包括单个字节输入输出、字符串(行)输入输出以及数据块输入输出

1  单个字节输入输出

在进行单个字节的输入输出操作时,可以使用fgetc函数和fputc函数。

文件输入输出单个

 int fgetc(FILE *fp);
 int fputc(int c, FILE *fp);

标准输入单个 int getchar();

 int fgetc(stdin);

标准输出单个

 int putchar(int c);

 int fputc(c, stdout);

1 /* example2.c */  2 #include 
3 #include
4 int main() 5 {
6 FILE *fp; /* 定义文件指针 */ 7 int ch; 8 fp = fopen("./tmp", "w+"); /* 打开文件 */ 9 if (fp == NULL) 10 {
11 perror("Open tmp failed "); /* 如果文件打开失败,输出错误信息 */ 12 exit(1); 13 } 14 while ((ch=getchar()) != '!') /* 从键盘读入字符,直到输入“!”结束 */ 15 {
16 fputc(ch, fp); /* 将读入的字符写到文件之中 */ 17 } 18 rewind(fp); /* 重设读写位置 */ 19 while ( (ch=fgetc(fp)) != EOF) /* 将文件内容一个字节一个字节地读出来,直到文件结束 */ 20 {
21 putchar(ch); /* 将读出的字符输出到屏幕 */ 22 } 23 fclose(fp); 24 return 0; 25 }

 

1 /* example4.c */  2 #include 
3 #include
4 #define BUFFER_SIZE 256 5 int main() 6 {
7 char buffer[BUFFER_SIZE]; /* 定义缓冲区 */ 8 int c; 9 FILE *fp; /* 定义文件指针 */ 10 fp = fopen("./hello.c", "r"); /* 打开文件 */ 11 if (fp == NULL) 12 {
13 perror("Open hello.c failed "); /* 如果文件打开失败,输出错误信息 */ 14 exit(1); 15 } 16 c = 1; 17 while (fgets(buffer, BUFFER_SIZE, fp) != NULL) /* 逐行读取文件内容 */ 18 {
19 printf("%d: %s", c++, buffer); /* 输出各行内容 */ 20 } 21 fclose(fp); /* 关闭文件 */ 22 return 0; 23 }

 

1 /* example5.c */  2 #include 
3 #include
4 #define BUFFER_SIZE 256 5 int main(int argc, char **argv) 6 {
7 char buffer[BUFFER_SIZE]; /* 定义缓冲区 */ 8 FILE *fp1, *fp2; /* 定义文件指针 */ 9 if(argc != 3) 10 {
11 printf("Too few arguments.\n"); 12 } 13 fp1 = fopen(argv[1], "r"); /* 打开源文件 */ 14 if (fp1 == NULL) 15 {
16 perror("Open file1 failed "); /* 如果文件打开失败,输出错误信息 */ 17 exit(1); 18 } 19 fp2 = fopen(argv[2], "w"); /* 打开目标文件 */ 20 if (fp2 == NULL) 21 {
22 perror("Open file2 failed "); /* 如果文件打开失败,输出错误信息 */ 23 exit(1); 24 } 25 while (!feof(fp1)) /* 测试是否读到文件末尾 */ 26 {
27 fgets(buffer, BUFFER_SIZE, fp1); /* 逐行读取源文件内容尾 */ 28 fputs(buffer, fp2); /* 逐行写入到目标文件之中 */ 29 } 30 fclose(fp1); /* 关闭源文件 */ 31 fclose(fp2); /* 关闭目标文件 */ 32 printf("Done!\n"); 33 return 0; 34 }

rewind函数
 
 void rewind(FILE * fp);

fseek函数
 
 int fseek(FILE *fp, long offset, int whence); fseek(fp, 0, SEEK_SET);

 fseek(fp, 0, SEEK_END);

ftell函数

 
 long ftell(FILE *fp);

1 /* example3.c */  2 #include 
3 #include
4 int main() 5 {
6 FILE *fp; /* 定义文件指针 */ 7 int i, ch, n; 8 fp = fopen("./tmp", "r"); /* 打开文件 */ 9 if (fp == NULL) 10 {
11 perror("Open tmp failed "); /* 如果文件打开失败,输出错误信息 */ 12 exit(1); 13 } 14 for (i=0; i<=7; i+=2) 15 {
16 fseek(fp, i, SEEK_SET); /* 重设读写位置 */ 17 n = ftell(fp); /* 获取当前的读写位置 */ 18 printf("Position : %ld\n", n+1); 19 ch=fgetc(fp); /* 从文件读入一个字节 */ 20 printf("Character : "); 21 putchar(ch); /* 将字符输出到屏幕 */ 22 printf("\n"); 23 } 24 fclose(fp); /* 关闭文件 */ 25 return 0; 26 }

3  数据块输入输出
对文件进行输入输出操作,也可以以数据块为单位进行。所谓数据块,是指一串固定长度的字节,例如一个整型数据、一个结构体,或一个固定长度的数组等。

 size_t fread(void *ptr, size_t size, size_t n, FILE *fp); size_t fwrite(void *ptr, size_t size, size_t n, FILE *fp);

1 /* example6.c */  2 #include 
3 #include
4 #define N 3 5 struct student /* 定义结构体 */ 6 {
7 int id; 8 int score; 9 }; 10 int main() 11 {
12 struct student array[N]; /* 定义结构体数组 */ 13 int i, n; 14 FILE *fp; /* 定义文件指针 */ 15 fp = fopen("./test.dat", "w"); /* 打开文件 */ 16 if (fp == NULL) 17 {
18 perror("Open test.dat failed "); /* 如果文件打开失败,输出错误信息 */ 19 exit(1); 20 } 21 for(i=0; i

 

1 /* example7.c */  2 #include 
3 #include
4 #define N 3 5 struct student /* 定义结构体 */ 6 {
7 int id; 8 int score; 9 }; 10 int main() 11 {
12 struct student x[N]; /* 定义缓冲区 */ 13 int i, n; 14 FILE *fp; /* 定义文件指针 */ 15 fp = fopen("./test.dat", "r"); /* 打开文件 */ 16 if (fp == NULL) 17 {
18 perror("Open test.dat failed "); /* 如果文件打开失败,输出错误信息 */ 19 exit(1); 20 } 21 n = fread(x, sizeof(struct student), N, fp); /* 从文件中读取N个结构体 */ 22 if (n != N) /* 如果实际读取长度小于N,输出具体原因 */ 23 {
24 if(feof(fp)) /* 测试是否读到文件末尾 */ 25 {
26 printf("End of file."); 27 } 28 else 29 {
30 printf("Read file error"); /* 输出错误信息 */ 31 } 32 } 33 printf("ID\tScore\n"); 34 for (i=0; i

三  格式化输入输出
格式化输出的函数

 int fprintf(FILE *fp, const char *format, ... );

 int printf(const char *format, ... );

 int fprintf(stdout, const char *format, ... );

format: % [+/-] [0] [m.n] [l] 转换字符

1.转换字符

2.指定输出精度 l

3. m.n

指定输出长度
如: 
 double x=0.123;
 printf("%9.4f\n", x);
  0.1230
9是总长度
这里空位补空格

4.空位填零 0

  int x=123;
  printf("%06d\n", x);
  000123

5.指定输出位置 + -

默认右对齐,加入-则可左对齐
char c[]=“ABCD”;
printf("%-5.3s\n", a);
printf("%+5.3s\n", a);

ABC

  ABC
 

格式化输入的函数

 int fscanf(FILE *fp, const char *format, ... );

 

 int scanf(const char *format, ... );
 
 int fscanf(stdin, const char *format, ... );
 

 scanf("%d %d", &x, &y);

 
 scanf("%d, %d", &x, &y);
 
 scanf("%10s", s); 10是读入总长度

1 /* example13.c */  2 #include 
3 #include
4 int main() 5 {
6 int x; 7 int sum = 0; 8 while (scanf("%d", &x) == 1) /* 读入整数,赋给变量x */ 9 {
10 sum += x; /* 累加 */ 11 printf("\t%3d\n", sum); /* 输出结果 */ 12 } 13 return 0; 14 }

其它应用

1 /* example14.c */  2 #include 
3 #include
4 int sum(int num, ...) /* 求和 */ 5 {
6 int v, i; 7 int sum = 0; 8 va_list vp; /* 定义指向可变参数列表的指针 */ 9 va_start(vp, num); /* 使指针指向参数列表中的第一个可选参数 */ 10 i = num; 11 while(i > 0) 12 {
13 v = va_arg(vp, int); /* 返回指针所指向的参数,并将其后移 */ 14 sum += v; 15 i--; 16 } 17 va_end(vp); 18 return sum; 19 } 20 int main() 21 {
22 printf("%d\n", sum(2, 2, 3)); /* 输出计算结果 */ 23 printf("%d\n", sum(4, 1, 2, 3, 4)); 24 return 0; 25 }

 

1 /* example15.c */  2 #include 
3 #include
4 int myprintf(char *format, ...) /* 定义可变参数函数 */ 5 {
6 va_list vp; /* 定义指向可变参数列表的指针 */ 7 int n; 8 va_start(vp, format); /* 使指针指向参数列表中的第一个可选参数 */ 9 n = vprintf(format, vp); /* 调用vprintf函数,通过va_list传入输入参数 */ 10 va_end(vp); 11 return n; 12 } 13 int main(void) 14 {
15 int x = 30; 16 float y = 0.36; 17 char *z = "abc"; 18 myprintf("x = %d\ny = %g\nz = %s\n", x, y, z); /* 调用前面定义的printf函数,将数据输出到屏幕 */ 19 return 0; 20 }

四   常见面试题
常见面试题1:调用fgets函数从文件中读取字符时,函数在满足什么条件时返回?

常见面试题2:调用fprintf函数进行格式化输出时,如何指定输出的长度和对齐方式?

转载于:https://www.cnblogs.com/zeedmood/archive/2012/03/25/2417019.html

你可能感兴趣的文章
running and coding
查看>>
实现QQ第三方登录、网站接入
查看>>
HTML CSS 层叠样式表 三
查看>>
Qt pro pri 文件学习1
查看>>
软件工程概论第六周学习进度条
查看>>
[思路]导入导出功能
查看>>
【iOS】UICollectionView自己定义Layout之蜂窝布局
查看>>
golang——(strings包)常用字符串操作函数
查看>>
发布aar到jcenter
查看>>
跨浏览器问题的五种解决方案
查看>>
XPath定位时,使用文本的方法小技巧。
查看>>
安装pandas报错(AttributeError: 'module' object has no attribute 'main')
查看>>
ch02 fundamental definition 01
查看>>
JSON解析
查看>>
Position is everything?(css定位学习的一些心得)(一)
查看>>
如何提高编程水平
查看>>
Jquery Uploadify3.21.与2.1版本 使用中存在的问题--记录三
查看>>
Linux查看进程的内存占用情况 分类: ubuntu ...
查看>>
[BZOJ 2818]Gcd
查看>>
FORM值传递与地址传递
查看>>