记录一下最近的学习,也和大家分享一下!谢谢!
标准I/O
一、标准I/O
1、读写文件
1)按一个字符读写fgetc、fputc
2)按行读写fgets、fputs
3)以二进制的形式读写文件fread、fwrite
首先是fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从文件流读取多个元素
参数:
ptr:用来存储读取元素
size:读取的元素大小(可以用sizeof(数据类型))
nmemb:一次读取的元素个数
stream:所要读取的文件流
返回值:
成功:读取到的元素个数(这个数字等于仅当size为1时传输的字节数)
失败:返回一个小于读取元素个数的数
到达文件末尾:返回0
例子:
执行并输出,结果为
hq@cvm-3jdq5xx28a225:/home/jlf/csdn/io$ ./a.out
qw88
下面是fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
从ptr读取多个元素到文件流中
参数:
stream:所要写入的文件流
返回值:同fread
例子:
fwrite.c程序
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp;
// w+ 以读写方式打开文件, 如果文件不存在则创建, 如果文件存在则清空
fp = fopen("1.txt", "w+");
if (fp == NULL)
{
perror("fopen");
return -1;
}
// 将buf中的内容写入到fp指向的文件中
char buf[] = "hello world";
fwrite(buf, 1, sizeof(buf), fp);
fclose(fp);
return 0;
}
这是未运行前的1.txt
编译执行之后
最后的红色nul是把‘\0’也给写进去了
2、文件定位操作:rewind、fseek、ftell
rewind
void rewind(FILE *stream);
功能:将文件位置指针定位到起始位置
当我们在用fgetc等函数时,读完之后文件位置指针会指向最后,使用rewind函数即可将其重新指向起始位置。
例子:
假设我们先将1.txt中的内容读到buf中,之后再修改开头的内容
1.txt:
Tomorrow is Wednesday.
rewind.c:
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp;
// r+ 以读写方式打开文件,文件必须存在
fp = fopen("1.txt", "r+");
// 判断文件是否打开成功
if (fp == NULL)
{
perror("fopen");
return -1;
}
// 把fp指向的文件的内容读到buf中
char buf[1024];
while (fgets(buf, sizeof(buf), fp) != NULL)
{
printf("%s", buf);
}
printf("\n");
// 这时候fp指向的文件的内容已经读完了,如果再次读取就会读到空,文件指针已经指向了文件的末尾
// 所以需要把文件指针重新指向文件的开头来写入Yesterday
rewind(fp);
// 把Yesterday写入到fp指向的文件中
fputs("Yesterday", fp);
fclose(fp);
return 0;
}
编译运行一下
hq@cvm-3jdq5xx28a225:/home/jlf/csdn/io$ gcc rewind.c
hq@cvm-3jdq5xx28a225:/home/jlf/csdn/io$ ./a.out
Tomorrow is Wednesday.
而1.txt变为
Yesterdayis Wednesday.
fseek
int fseek(FILE *stream, long offset, int whence);
功能:文件的定位操作
参数:
stream:文件流指针
offset:偏移量:正数表示向后文件尾部偏移,负数表示向文件开头偏移
whence:相对位置
SEEK_SET:相对于文件开头
SEEK_CUR:相对于文件当前位置
SEEK_END:相对于文件末尾
返回值:成功:0
失败:-1
注:当打开文件的方式为a或a+时,fseek不起作用
直接上例子:
假设我们先将1.txt中的内容读到buf中,之后再修改文件中第四个位置的内容为“X”
1.txt:
Tomorrow is Wednesday.
fseek.c:
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp;
// r+ 以读写方式打开文件,文件必须存在
fp = fopen("1.txt", "r+");
// 判断文件是否打开成功
if (fp == NULL)
{
perror("fopen");
return -1;
}
// 把fp指向的文件的内容读到buf中
char buf[1024];
while (fgets(buf, sizeof(buf), fp) != NULL)
{
printf("%s", buf);
}
printf("\n");
// 将文件指针移动到文件的第4个字节处,修改文件的第4个字节为“X”
// 从文件的开头开始计算,第一个字节的偏移量为0
fseek(fp, 3, SEEK_SET);
fputc('X', fp);
fclose(fp);
return 0;
}
编译运行,结果1.txt变为:
TomXrrow is Wednesday.
ftell
long ftell(FILE *stream);
功能:获取当前的文件指针位置
参数:要检测的文件流
返回值:成功:当前的文件指针位置,出错:-1
例子:
#include <stdio.h>
int main(int argc, char const *argv[])
{
FILE *fp;
// r+ 以读写方式打开文件,文件必须存在
fp = fopen("1.txt", "r+");//1.txt内容为:TomXrrow is Wednesday.
// 判断文件是否打开成功
if (fp == NULL)
{
perror("fopen");
return -1;
}
// 获取fp指向的文件的当前位置
int pos = ftell(fp);
printf("pos: %d\n", pos);
// 把fp指向的文件的内容读到buf中
char buf[1024];
while (fgets(buf, sizeof(buf), fp) != NULL)
{
printf("%s", buf);
}
printf("\n");
// 获取fp指向的文件的当前位置
pos = ftell(fp);
printf("pos: %d\n", pos);
fclose(fp);
return 0;
}
第一次ftell的时候,文件位置指针在文件开头,而第二次ftell的时候,文件的内容已被读到buf里,文件位置指针也就指向了文件末尾。
故输出结果为:
hq@cvm-3jdq5xx28a225:/home/jlf/csdn/io$ ./a.out
pos: 0
TomXrrow is Wednesday.
pos: 22