一 标准输入输出的基本操作
文件控制结构中包含处理文件所需的全部信息,例如文件名、文件当前的读写位置、用于该文件读写的内存缓冲区位置等。打开文件时,系统会在内存中自动建立该文件的控制结构。关闭文件时,文件控制结构被释放。在对文件进行操作之前,要首先获取文件的指针,即指向文件控制结构的指针,后续操作都通过该指针进行。标准输入输出时,有3个比较特殊的文件,它们是:标准输入文件(stdin):一般为键盘;标准输出文件(stdout):一般为显示器;
标准错误输出文件(stderr):一般为显示器。
1 文件的打开
操作文件之前要打开文件,打开文件主要是在系统中分配一些资源用于保存该文件的状态信息,并获取文件的指针,以后调用其它函数对文件进行读写操作时都要提供这个指针。2 文件的关闭
FILE *fopen(const char *filename, const char *modes);对文件操作完成后,应该关闭文件,进而释放文件所占用的系统资源。文件关闭之后,文件指针将不再有效,用户也就无法通过该指针操作文件。int fclose(FILE *fp);
1 /* example1.c */ 2 #include3 #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 }
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 #include3 #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 #include3 #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 #include3 #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 }
fseek(fp, 0, SEEK_END);
ftell函数
long ftell(FILE *fp);1 /* example3.c */ 2 #include3 #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 }
1 /* example6.c */ 2 #include3 #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 #include3 #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.12309是总长度这里空位补空格4.空位填零 0
int x=123; printf("%06d\n", x); 0001235.指定输出位置 + -
默认右对齐,加入-则可左对齐如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 #include3 #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 #include3 #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 #include3 #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 }