#include <stdio.h>
#include <stddef.h>
#include <string.h>
int main() {
FILE * iostream = fopen("fopenfile", "r");
if (iostream == NULL) {
perror("流打開錯誤");
return -1;
}
char c;
while ((c = getc(iostream)) != -1) {
printf("读取的字符是:");
putchar(c);
printf("\n");
}
if (feof(iostream)) {
printf("读取到文件末尾结束\n");
}
if (ferror(iostream)) {
printf("读取出现异常结束\n");
}
return 1;
}
读取的字符是:a
读取的字符是:b
读取的字符是:c
读取的字符是:d
读取的字符是:e
读取的字符是:
读取到文件末尾结束
整行读写
写函数
int fputs (constchar *__restrict __s, FILE *__restrict __stream);
int puts (constchar *__s);
返回值:成功返回非负值,错误返回EOF
读函数
char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
char *gets (char *__s)
返回值:成功返回buf, 失败或达到文件结尾返回NULL
举例:
#include <stdio.h>
#include <string.h>
int main() {
FILE *iostream = fopen("fopenfile", "r+");
if (iostream == NULL) {
perror("文件打开错误!");
return -1;
}
int reval = fputs("hello world\n", iostream);
if (reval == -1) {
perror("文件写入失败!");
return -1;
}
fflush(iostream);
fclose(iostream);
iostream = fopen("fopenfile", "r+");
if (iostream == NULL) {
perror("文件打开错误!");
return -1;
}
char buf[1000];
memset(buf, '\0', 1000);
char *getval = fgets(buf, 1000, iostream);
printf("读入一行数据是:%s", buf);
}
二进制IO
前面说到的单字节以及整行读写,如果要写一个结构则需要每一个结构项的读写很麻烦,这就需要用到2进制IO
读操作
size_t read (void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream)
__pt:结构体(数据)指针
__size:单个结构体大小
__n:结构体数量
__stream:文件流
返回值:读或写的对象数
写操作
size_t fwrite (constvoid *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __s);
举例:
#include <stdio.h>
#include <string.h>
typedef struct {
int no;
char name[100];
long tel;
} Info;
int main(int argc, char *argv[]) {
if (0 == strcmp(argv[1], "read")) {
FILE *ios = fopen("binaryfile", "r");
Info info;
fread(&info, sizeof(Info), 1, ios);
printf("no=%d\n", info.no);
printf("name=%s\n", info.name);
printf("tel=%ld\n", info.tel);
if (getc(ios) == -1) {
if (feof(ios)) {
printf("读取到文件末尾结束\n");
}
if (ferror(ios)) {
printf("读取出现异常结束\n");
}
}
} else if (0 == strcmp(argv[1], "write")) {
FILE *ios = fopen("binaryfile", "w");
Info info;
info.no = 1;
info.tel = 1234567;
char *name = "hello";
memcpy(info.name, name, strlen(name) + 1);
fwrite(&info, sizeof(Info), 1, ios);
}
return 1;
}
执行结果:
no=1
name=hello
tel=1234567
读取到文件末尾结束
说明:
1.生成的文件为2进制文件,如打开看到的会是乱码
2.最后需要在此尝试读入一个字符,那么流才会结束,才会使用feof等判断
文件流定位
可以设置文件位置指示器来影响一个文件读取,用法和sleek一致
获取当前文件位置指示器
long int ftell (FILE *__stream)
返回值:当前文件位置指示器
int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos);
返回值:成功返回0,失败返回非0值
当前文件位置指示器
int fseek (FILE *__stream, longint __off, int __whence);
返回值:成功返回0,失败返回非0值
int fsetpos (FILE *__stream, constfpos_t *__pos);
返回值:成功返回0,失败返回非0值
重定位文件位置指示器
void rewind (FILE *__stream);
相当于(void)fseek(stream, 0L,SEEK_SET)
返回值:成功返回0,失败返回非0值
临时文件
char *tmpnam (char *__s)
char *tempnam (constchar *__dir, constchar *__pfx)
FILE *tmpfile (void) __wur;
int mkstemp (char *__template)