1.Linux标准IO编程
1.1Linux系统调用和用户编程接口
1.1.1系统调用
用户程序向操作系统提出请求的接口。不同的系统提供的系统调用接口各不相同。
继承UNIX系统调用中最基本和最有用的部分。
调用按照功能分:进程控制、进程间通讯、文件系统控制、存储管理、网络管理、套接字控制、用户管理。
1.1.2用户编程接口
实际开发使用的是用户编程接口:
(1)、系统调用接口功能非常简单,无法满足程序的需求。
(2)、不同操作系统的系统调用接口不兼容,程序移植时工作量大。
1.2Linux标准编程接口
1.2.1标准IO的由来:指的是ANSI C中定义的用于IO操作的一系列函数。
(1)、具有更好的移植性;(2)、可以减少系统调用的次数,提高系统效率(在用户空间创建缓冲区)。
1.2.2流的含义
缓冲类型:(1)、全缓冲;(2)、行缓冲;(3)、无缓冲;
1.3标准IO编程
1.3.1流的打开:
FILE *fopen(const char *path, const char *mode);
1.3.2流的关闭:
int fclose(FILE *fp);
1.3.3错误处理:
void perror(const char *s);
1 /*******************************************************************
2 * > File Name: 01-perror.c
3 * > Author: fly
4 * > Mail: XXXXXXXX@icode.com
5 * > Create Time: Tue 29 Aug 2017 10:43:49 PM CST
6 ******************************************************************/
7
8 #include <stdio.h>
9
10 int main(int argc, char* argv[])
11 {
12 FILE *fp; //定义一个文件指针
13
14 if((fp = fopen("1.txt","r")) == NULL){
15 perror("Open 1.txt error :"); //输出错误信息
16 return (-1);
17 }else{
18 printf("Open 1.txt successed , fp = %p\n", fp);
19 }
20
21 fclose(fp);
22
23 return 0;
24 }
char *strerror(int errnum);
1 /*******************************************************************
2 * > File Name: 01-strerror.c
3 * > Author: fly
4 * > Mail: XXXXXXXX@icode.com
5 * > Create Time: Tue 29 Aug 2017 11:22:07 PM CST
6 ******************************************************************/
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <errno.h>
11
12 int main(int argc, char* argv[])
13 {
14 FILE *fp;
15
16 if((fp = fopen("1.txt", "r")) == NULL){
17 printf("Fopen 1.txt error : %s\n", strerror(errno));
18 return (-1);
19 }
20
21 fclose(fp);
22
23 return 0;
24 }
1.3.4流的读写:
1.按字符(字节)输入/输出
字符输入:
int fgetc(FILE *stream);
int getc(FILE *stream);
int getchar(void);
字符输出:
int fputc(int c, FILE *stream);
int putc(int c, FILE *stream);
int putchar(int c);
1 /*******************************************************************
2 * > File Name: 03-fput.c
3 * > Author: fly
4 * > Mail: XXXXXXXX@icode.com
5 * > Create Time: Tue 29 Aug 2017 11:51:13 PM CST
6 ******************************************************************/
7
8 #include <stdio.h>
9
10 int main(int argc, char* argv[])
11 {
12 int c;
13
14 while(1){
15 c = fgetc(stdin); //从标准输入流获取一个字符
16 if((c >= '0') && (c <= '9'))
17 fputc(c, stdout); //如输入的是数字,就输出
18 if(c == '\n'){
19 puts("");
20 break; //换行符,跳出循环
21 }
22 }
23
24 return 0;
25 }
2.按行输入/输出
行输入:
char *fgets(char *s, int size, FILE *stream);
char *gets(char *s);
行输出:
int fputs(const char *s, FILE *stream);
int puts(const char *s);
1 /*******************************************************************
2 * > File Name: 04-fgets.c
3 * > Author: fly
4 * > Mail: XXXXXXXX@icode.com
5 * > Create Time: Wed 30 Aug 2017 11:39:05 PM CST
6 ******************************************************************/
7
8 #include <stdio.h>
9 #include <string.h>
10
11 int main(int argc, char* argv[])
12 {
13 static int line = 0;
14 char buf[128];
15 FILE *fp;
16
17 if(argc < 2){
18 printf("Usage : %s <file> \n", argv[0]);
19 return (-1);
20 }
21
22 if((fp = fopen(argv[1], "r")) == NULL){
23 perror("Fail to fopen :");
24 return (-1);
25 }
26
27 while(fgets(buf, 128, fp) != NULL){
28 if(buf[strlen(buf) - 1] == '\n')
29 line++;
30 }
31
32 printf("The line of %s is %d\n", argv[1], line);
33
34 return 0;
35 }
3.以指定大小为单位读写文件
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
1.3.5流的定位
int fseek(FILE *stream, long offset, int whence);
whence:SEEK_SET, SEEK_CUR, or SEEK_END:文件起始、当前、末尾读写位置;
long ftell(FILE *stream);
1 /*******************************************************************
2 * > File Name: 05-ftell.c
3 * > Author: fly
4 * > Mail: XXXXXXXX@icode.com
5 * > Create Time: Thu 31 Aug 2017 12:25:37 AM CST
6 ******************************************************************/
7
8 #include <stdio.h>
9
10 int main(int argc, char* argv[])
11 {
12 FILE *fp;
13
14 if(argc < 2){
15 printf("Usage : %s file \n", argv[0]);
16 return (-1);
17 }
18
19 if((fp = fopen(argv[1], "r")) == NULL){
20 perror("Fail to fopen :");
21 return (-1);
22 }
23
24 fseek(fp, 0, SEEK_END);
25
26 printf("The size of %s is %ld bytes\n", argv[1], ftell(fp));
27
28 return 0;
29 }
1.3.6格式化输入与输出
输入:
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
输出:
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
1.4实验内容
1.4.1文件的复制
1.实验目的:通过实现文件的复制,掌握流的基本操作。
2.实验内容:在程序中分别打开源文件和目标文件。循环从源文件中读取内容并写入目标文件。
3.实验步骤:(1)、检查参数→打开源文件→打开目标文件→循环读写文件→关闭文件。
(2)、编写代码。
1 /*******************************************************************
2 * > File Name: 06-mycopy.c
3 * > Author: fly
4 * > Mail: XXXXXXXX@icode.com
5 * > Create Time: Fri 01 Sep 2017 11:04:46 PM CST
6 ******************************************************************/
7
8 #include <stdio.h>
9 #include <errno.h>
10 #include <string.h>
11 #define N 64
12
13 #define ENABLE 1
14 #define DISABLE 0
15 #define ERR_T_ONE DISABLE
16 #define ERR_T_TWO DISABLE
17
18 int main(int argc, char* argv[])
19 {
20 char buf[N];
21 FILE* fps, *fpd;
22 int n;
23
24 /*1.判断命令行参数*/
25 if(argc < 3){
26 fprintf(stderr, "Usage : %s <src_file> <dst_file>\n", argv[0]);
27 return (-1);
28 }
29
30 /*2.打开源文件*/
31 if((fps = fopen(argv[1], "r")) == NULL){
32 fprintf(stderr, "Fopen %s error : %s\n", argv[1], strerror(errno));
33 return (-1);
34 }
35
36 /*3.打开目标文件*/
37 if((fpd = fopen(argv[2], "w")) == NULL){
38 fprintf(stderr, "Fopen %s error : %s\n", argv[2], strerror(errno));
39 fclose(fps);
40 return (-1);
41 }
42
43 /*4.复制文件*/
44 while((n = fread(buf, 1, N, fps)) > 0){
45 #if (ERR_T_TWO == ENABLE)
46 fwrite(buf, 1, N, fpd); //末尾会多写入11个填充字符
47 bzero(buf, sizeof(buf));
48 #elif(ERR_T_ONE == ENABLE)
49 fwrite(buf, 1, N, fpd); //多写入最后一次的前一次的最后11个字符
50 #else
51 fwrite(buf, 1, n, fpd);
52 #endif
53 }
54
55 fclose(fps);
56 fclose(fpd);
57
58 return 0;
59 }
1.4.2循环记录系统时间
1.实验目的:获取系统时间→在程序中延时→流的格式化输出。
2.实验内容:程序中每隔一秒读取一次系统时间并写入文件。
3.实验步骤:(1)、设计流程:打开文件→获取系统时间→写入文件→延时1s→返回第二步(获取系统时间)。
(2)、编写代码。
1 /*******************************************************************
2 * > File Name: 07-getTime.c
3 * > Author: fly
4 * > Mail: XXXXXXXX@icode.com
5 * > Create Time: Sat 02 Sep 2017 10:15:07 PM CST
6 ******************************************************************/
7
8 #include <stdio.h>
9 #include <time.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <unistd.h>
13
14 #define BUF_LENGTH 64
15
16 int main(int argc, char* argv[])
17 {
18 int n = 0;
19 char buf[BUF_LENGTH];
20 FILE *fps;
21 time_t t;
22
23 /*1.判断命令行参数*/
24 if(argc < 2){
25 sprintf(buf,"Usage : %s <file_name>\n", argv[0]);
26 printf("%s", buf);
27 return (-1);
28 }
29
30 /*2.打开文件*/
31 if((fps = fopen(argv[1], "w")) == NULL){
32 fprintf(stderr, "Fopen %s error :%s\n", argv[1], strerror(errno));
33 return (-1);
34 }
35
36 /*2.每隔1秒,获得时间,写入文件,记录下来*/
37 while(1){
38 n ++;
39 t = time(NULL);
40 fprintf(fps, "Good Luck %4d : %s", n, ctime(&t));
41 fprintf(stdout, "%4d\n", n);
42 sleep(1);
43 fflush(NULL);
44 }
45
46 fclose(fps);
47
48 return 0;
49 }